home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
FM Towns: Free Software Collection 7
/
FM Towns Free Software Collection 7.iso
/
ms_dos
/
ct
/
ct_all
next >
Wrap
Text File
|
1993-11-30
|
165KB
|
5,446 lines
# DIVIDE_START=update.doc
-------------------------- ct005u --------------------------
1993.10.4
・フリコレ7 修正版
-------------------------- ct005t --------------------------
1993.10.2
・NIFTYの新しいMAILの形式に対応で、日付処理の修正を忘れていた。
-------------------------- ct005s --------------------------
1993.10.1
・NIFTYの新しいMAILの形式に対応。
・HPの設置者IDとMAIL発信人IDが同じだとツリーがうまく作れない
バグ修正。
・起動時、引数を表示していたが、テスト終了につき削除。
-------------------------- ct005r --------------------------
1993.9.15
・新オプション追加。
「-w」の次の引数はTMPディレクトリを指す。
他のオプションとの優先順位は、
1.「-w」 TMPディレクトリ
2.「-o」 出力ディレクトリ
3.「その他」
ということで、次のように使います。
>ct -ow TmpDir OutDir InputDir
あるいは次のように使っても良いです。
>ct -o OutDir -w TmpDir InputDir
・CTDの処理の変更により、「-e」と「-E」のオプションが不用になる。
削除。
-------------------------- ct005q --------------------------
1993.9.11
・リアルメモリーの確保の際、標準関数の為に残しておく容量を設定するように変
更した。
現在、設定値は 8L キロバイトである。
・「-z」オプションを指定すると vmap を起動するようにした。
-------------------------- ct005p --------------------------
1993.9.7
・マトコメ・ファイルの作り方の変更。
フォーラムの会議室とPATIO以外は指定発言以降の全発言をファイルに書き
出すようにする。
-------------------------- ct005o --------------------------
1993.9.5
・非公開オプション「-e」と「-E」の追加。
使い方:
ct -e DirName
「DirName」にあるファイルを検索して発言を見つけTMPファイルを作る。
TMPファイルを作って終了する。
ct [options] -E
TMPファイルを検索してツリー・ファイルを作る。
TMPファイルは検索後削除する。
この2つのオプションはペアで使うこと。
-------------------------- ct005n --------------------------
1993.9.1
・非公開オプション「-l」(小文字のL)追加。
「comtree0.tmp」の行数を次の引数に指定すると「comtree.tmp」を読んで
「comtxt.tmp」を作る。
使い方:
ct -o f:\tmp -l 97
こうすると、「f:\tmp」にある「comtree.tmp」を読み込み、
「f:\tmp」に「comtxt.tmp」を作る。
FAPXは、「comtxt.tmp」をメモ画面に読み込むのみ。
〔注意1〕上の使い方以外は不可。引数の順番を守ること。
〔注意2〕あらかじめ「comtree.tmp」を作っておくこと。
〔問題点1〕:「会議室.tmp」「DL.tmp」が削除される。
解決の方法が見つからない。
〔問題点2〕:デバッグが不充分。
将来的には別プログラムとする予定。(プログラムサイズを小さくする為)
-------------------------- ct005m --------------------------
1993.8.31
・「comtree.tmp」の内容の変更。
1.2行目の末にコメントレベルの値を追加。
>"%5d %5d %8ld %8ld %5d %5d %10s %2d\n"
| | | | | | | ↓
| | | | | | ↓ コメントレベル ← 追加(☆)
| | | | | ↓ 発言日時
| | | | ↓ 発言の終了行
| | | ↓ 発言の開始行
| | ↓ 発言の終了バイト数
| ↓ 発言の開始バイト数
↓ コメント元番号
発言番号
ただし、
「フォーラム名変更」の場合は -2
「会議室名変更」の場合は -1
とする。
DLの場合、会議室の発言があった場合は -1 となり、会議室の発言が無か
った場合は -2 となる。
2.フォーラムの会議室以外の「フォーラム名変更」の題名の付け方を変える。
例:HP:GHH01217 のHPです
PATIO:GHH01217 のPATIOです
MAIL:GHH01217 のMAILです
3.「フォーラム名変更」「会議室名変更」の1行目の形式を変更。
「CHANGE:FORUM フォーラム名変更」
「CHANGE:MES 会議室名変更」
とする。
4.「フォーラム名変更」「会議室名変更」の2行目の形式を変更。
発言の2行目と同じ形式にする。
「 0 0 0 0 0 0 0 -2」
「 0 0 0 0 0 0 0 -1」
変更するフォーラム名等は3行目に移動。
-------------------------- ct005L --------------------------
1993.8.30
・まだリアルメモリー不足で起動できないという。
ヒープ領域の確保量を減らす。
ファイル入力用バッファ領域 20kバイト
オンメモリー処理(IDX2)用 64kバイト
オンメモリー処理(IDXS)用 42kバイト
-------------------------- ct005k --------------------------
1993.8.30
・MopTerm上から実行すると、リアルメモリー不足が発生する。
ヒープ領域の確保量を減らす。
ファイル入力用バッファ領域 31kバイト
オンメモリー処理(IDX2)用 64kバイト
オンメモリー処理(IDXS)用 48kバイト
・「comtree.tmp」の1行目が「FORUM:xxxx MES:dd」となっているはずなのに
「FORUM:xxxx MESdd」となっていた。修正。
-------------------------- ct005j --------------------------
1993.8.29
・「comtxt.tmp」を作ることの高速化。
1993.8.28
・1つの会議室での発言数が5040個より大きい場合の処理の追加。
・オンメモリーでの処理完了。
0.05i からの差分を作る。
1993.8.27
・発言の数が少ない時はオンメモリーで処理する部分を追加。
idx2 idxs
-------------------------- ct005i --------------------------
1993.8.26
・0.05h のバグ修正。
-------------------------- ct005h --------------------------
1993.8.26
・せっかくDLにアップしたが、バグがあり、削除依頼を出した。
1993.8.26
・DLにアップ。FTOWNS1-DL2
-------------------------- ct005g --------------------------
1993.8.25
・DLのバグ修正。
-------------------------- ct005f --------------------------
1993.8.25
・DLのバグ修正。
-------------------------- ct005e --------------------------
・DLのバグ修正。
-------------------------- ct005d --------------------------
1993.8.23
・課金情報に対応。
-------------------------- ct005c --------------------------
1993.8.23
・「今週のお知らせ」の不具合の修正。
・クリッピングサービス対応。
-------------------------- ct005b --------------------------
1993.8.22
・「今週のお知らせ」に対応。
-------------------------- ct005a --------------------------
1993.8.20
・DLに対応。
・発言番号は unsigned int で処理することにする。順次変更。
・ファイルのサイズが0の場合、読み込めないという不具合の修正。
・データライブラリー(DL)一覧用のファイルを作るようにした。
ファイル名「DL.TMP」
・コメント元発言が別のファイル等で見つからなかった場合、処理されない発言が
発生していた。バグ修正。
・while ( kbhit() ) getch(); を Check1File と Sort1Kaigi に潜ませるように
変更。会議室毎に終了判定を行うようにしたので反応が良くなる。
・同じフォーラムの同じ会議室で複数の日付の発言がある場合で、コメント元番号
が1番の時、うまくツリーが作れないバグ修正。
・同じフォーラムの同じ会議室で、発言番号がより小さくなった時、会議室名を表
示するようにした。(「comtree0.tmp」にも書き出される)
-------------------------- ct004q --------------------------
1993.8.19
・同一フォーラム、同一会議室のコメントツリーの作成にバグあり。修正。
このバグは ct004p で入れたもの。
-------------------------- ct004p --------------------------
1993.8.18
・1つの会議室で処理できる発言の数を増やす工夫。
(1) 発言番号・コメント元番号を long で扱っているが、unsigned int にする。
(2) コメントツリーのレベルが深すぎる場合の処理を変更する。
-------------------------- ct004o --------------------------
1993.8.15
・今度こそフリコレ7応募版に。
・発言番号、コメント元番号を long で処理する。
-------------------------- ct004n --------------------------
1993.8.15
・フリコレ7応募版にしたかったのだが………。
・HPの発言の切り出しに不具合あり。修正。
-------------------------- ct004m --------------------------
1993.8.13
・@ファイルに対応。
使い方:ct @FileName
ファイルの内容は、コマンドラインの書式と同じ。
ファイルの中身に「@FileName」を入れても良い。しかし、スタック領域不足
でハングするかも知れない。
また、
ct -o @deffile
として、deffile の中身の第1番目の数に出力ディレクトリの指定をする、とい
うような使い方はできない。上の用法だと @deffile というディレクトリに処理の
結果を書き出そうとする。(当然エラーとなるだろう)
・オプションスイッチの考え方を変更。
「-」が頭に無い引数は、入力ファイル名、または入力ディレクトリ名である。
使い方:ct InputDir
ct InputFileName
ct InputDir1 InputDir2
名前にはワイルドカードが使える。
「-o」の次の引数は、出力ディレクトリとする。
使い方:ct -o OutDir
「-o」引数は、入力するファイルの指定よりも先に行うこと。そうでないと
「会議室.tmp」が指定のディレクトリではなく、カレント・ディレクトリに作
成されてしまう。
例: 途中経過の表示無し
「comtxt.tmp」の出力無し
入力「f:\log」
出力「g:\tmp」
の場合の指定の仕方:(下の指定はいずれも同じ結果を生じる)
ct -DoT g:\tmp f:\log
ct -DTo g:\tmp f:\log
ct -DT -o g:\tmp f:\log
ct -D -To g:\tmp f:\log
ct -D -T -o g:\tmp f:\log
ct -DT f:\log -o g:\tmp
なお、次のようにすると、処理中の発言を表示するがツリーは画面に表示しない
ct f:\log -DTo g:\tmp
この件に対応の為、引数の処理の部分を修正。
・会議室名の取得部分の修正。
1993.8.12
・検索するファイルの1行目に「ID (改行のみ:自分のHP)」があると、きちんと
HP名が入力できないバグの修正。
-------------------------- ct004L --------------------------
1993.8.12
1.「[ESC]で中断」を入れる。
1993.8.11
1.CATLOG整理済ファイルの検索時、カレント・ファイル(とCATL
OGの方では言っています---勝手に)だけを検索するオプションの設定。
オプション名「A」----カレント・ファイルのみ検索する。
オプション名「a」----全てのファイルを検索する(デフォルト値)。
2.ファイルを指定してツリーを作る際、ファイルサイズの指定に不具合があ
り、指定のファイルを読み込まない場合が発生する不具合の修正。
-------------------------- ct004k --------------------------
1993.8.11
・オプションスイッチ名の変更。
-D ・・・・・・・ 標題等を画面上に表示しない
-d ・・・・・・・ * 標題等を画面上に表示する
-F数 ・・・・・ 数Kバイトまでファイルを検索する
-f ・・・・・・・ * サイズで中断しない
-R ・・・・・・・ サブディレクトリのファイルを検索しない
-r ・・・・・・・ * サブディレクトリのファイルを検索する
-T ・・・・・・・ 発言の本体を出力しない
-t ・・・・・・・ * 発言の本体を出力する
-1 ・・・・・・・ ベタのまま、発言の標題を表示する
-2 ・・・・・・・ * コメントツリーで発言の標題を表示する
* は、デフォルトの設定です
1.MS-DOS の環境変数 tmp を参照して、内部のTMPファイルはそこに作る。
なければ OutDir に作る。
2.MS-DOS の環境変数 ctusr を参照して、
(1) ディレクトリを再帰的に検索しない指定
(2) 読み込むログのサイズを制限する
なければ、今まで通り。
3.while ( kbhit() ) getch(); を Check1File と SortMainONFileSub に潜ませる。
-------------------------- ct004j --------------------------
1993.8.10
・「comtree.tmp」に書き出す行数を2行にする。
1行目:発言に関するデータ
フォーラム名等が変わった場合は「フォーラム名変更」が入る
会議室番号が変わった場合は 「会議室名変更」が入る
2行目:ファイル名
「フォーラム名変更」「会議室名変更」の場合、それぞれの
名前が入る。
-------------------------- ct004i --------------------------
1993.8.10
・CATLOGで整理したファイルの内、HP、PATIO、MAILの場合、
フォーラム名変更の出力がうまく行っていなかった。修正。
・「comtree.tmp」に書き出す行数を3行にする。
1行目:フォーラム名の行
フォーラム名等が変わった場合は「フォーラム名変更」が入る
会議室番号が変わった場合は 「会議室名変更」が入る
2行目:発言に関するデータ
「フォーラム名変更」「会議室名変更」の場合、それぞれの
名前が入る。
3行目:ファイル名
「フォーラム名変更」「会議室名変更」の場合、改行のみ。
-------------------------- ct004h --------------------------
1993.8.9
・「comtree.tmp」に書き出す行数を4行にする。
1行目:フォーラム名 会議室番号 */
フォーラム名等が変わった場合は「フォーラム名変更」が入る
会議室番号が変わった場合は 「会議室名変更」が入る
2行目:フォーラム名の行
「フォーラム名変更」「会議室名変更」の場合、それぞれの
名前が入る。
3行目:発言に関するデータ
4行目:ファイル名
-------------------------- ct004g --------------------------
1993.8.9
・内部のTMPファイルの中身の変更。
1行目:フォーラム名と会議室番号を書き出す
2行目:ForumNameLine を書き出す
3行目:会議室名の行を書き出す
4行目:ファイル名を書き出す
5行目:発言に関するデータを書き出す
6行目:発言の題名
>1993.6.28
>・「comtree.tmp」ファイルには発言の標題のみを書き込むことにする。
> いつでも復旧できるように #ifndef ONLY_HYOUDAI として書き込む部分を削除す
>る。
を削除。
・main.c が大きくなって来たので check.c と sort.c の2つの分割。
・発言の終了判定に以下の2つの文字列を追加した
"ID (改行のみ:自分のHP)"
"ID (改行のみ:自分のパティオ)"
-------------------------- ct004f --------------------------
1993.8.8
・CATLOGの出力ディレクトリに対して実行した場合、会議室名が全部同じにな
ってしまうバグの修正。
・「フォーラム名変更」の場合「comtree.tmp」にフォーラム名の行が書き出されて
いない。
・「会議室変更」を「会議室名変更」に変更。
-------------------------- ct004e --------------------------
1993.8.8
・makeIndex でメールの処理にバグがあった。修正。
-------------------------- ct004d --------------------------
1993.8.7
・「fapxtree.tmp」を作らないモードを作った。(標準で作らないということ)
ct.h に MAKE_FAPXTREE_TMP を設定してある。それを #undef すると、作らないモ
ードになる。
また、このバージョンは、VERIFY == NO で作った。どれぐらい速くなるのかを調
べるためである。
-------------------------- ct004c --------------------------
1993.8.6
・PATIOの処理で発言日時の処理にバグがあった。修正。
-------------------------- ct004b --------------------------
1993.8.4
・検索する発言にMAILを追加。
・発言を見つけた時の、発言に関するデータを書き出すファイル名を変更。
ALL_MAIL "$A0" /* 1つにまとめた MAIL ファイルである */
BILL "$B0" /* 利用料金情報である */
CLIP "$C0" /* クリッピングサービスである */
MES "$Fx" /* フォーラムの会議室である */
HP "$H0" /* Home Party である */
COLLECT_ID "$I0" /* ID収集ファイルである */
LIB "$L0" /* LIB の一覧である */
COLLECT_LIB "$L1" /* IDによる LIB の収集ファイルである */
MAIL "$M0" /* 電子メールである */
PATIO "$P0" /* PATIO である */
-------------------------- ct004a --------------------------
1993.8.3
・PATIO関連の不具合を修正。
1993.8.2
・仕様の変更
1.オプション・スイッチの内、会議室指定、HP指定、PATIO指定を削除。
2.1ファイル指定、複数ファイル指定を削除。
3.入力ディレクトリは必ず指定するように変更。
カレント・ディレクトリの場合は「.」を使用すること。
指定の入力ディレクトリがディレクトリであれば、そのディレクトリの下の全
ファイルを検索して発言を見つけるように変更。
4.CATLOGで整理してできたファイルを検索するのか、生のログ・ファイル
を検索するのかの指定も、無効とする。
-------------------------- ct003p --------------------------
1993.7.26
・発言の標題の処理がうまくいっていなかった。修正。
・「comtree.tmp」と「comtree0.tmp」の処理が一部うまくいっていなかった。修正。
-------------------------- ct003o --------------------------
1993.7.25
> 1.ファイルの指定をサポートする。
> 2.処理中である事を動きの有る方法でユーザーに伝える。
-------------------------- ct003n --------------------------
1993.7.24
・コメントツリーの表示を下のJIS罫線を使って行うように変更。
>>; 初期値(機種依存なし) :+-+-| +-
>>; FM-R系で新JIS機種 :┣┗┃╋
-------------------------- ct003m --------------------------
1993.7.24
・発言の検索の不具合の修正。
問題点:PATIOを指定しているのにフォーラムの発言を検索してしまう。
これは、フォーラムの会議室とPATIOの、それぞれの発言番号の行の形式が同
じなため、誤動作するものである。
そこで、「StartMesSw」というスイッチを設け、フォーラムの入口と認識した場合
のみ、ONにし、HP、PATIOの入口の場合はOFFとするようにした。
・「comtree.tmp」「comtree0.tmp」「fapxtree.ymp」に書き出す標題の行を標題の
部分だけにした。
・「comtree.tmp」「comtree0.tmp」「fapxtree.ymp」の行の統一を図った。
「comtree0.tmp」と「fapxtree.ymp」が同じ行数だけあるようにした。
「comtree0.tmp」の行数の8倍の所に「comtree.tmp」があるようにした。
なお、「fapxtree.ymp」には、「」の1行を追加するようにした。
また、「comtree.tmp」には、「フォーラム名変更」あるいは「会議室変更」の
1行と、それぞれフォーラム名の行、会議室名の行を追加し、さらに6行の空行を
追加するようにした。
・検索するファイルの指定の不具合を修正。
かなり混みいった問題である。ソースの Check1File の部分を見ること。
-------------------------- ct003l --------------------------
1993.7.23
・操作性の統一を図った。
1.新しいオプションの追加。
「-m」フォーラムの会議室の発言を検索する
2.オプションスイッチ名の変更。
「-n」→「-c」………CATLOGで整理したファイルを使用する
「-2」→「-a」………全ての会議室、HP、PATIOの発言を検索する。
3.これらのオプションが設定されていない場合は、発言を検索できない。
・ドキュメントの作成。
readme.doc と ct.ggg
-------------------------- ct003k --------------------------
1993.7.22
・「fapxtree.tmp」の「date=xxxx」の後ろに「;」を付けるのを忘れていた。修正。
・「fapxtree.tmp」の「title=」の後ろには、NIFTYの発言番号の行をそのまま
書き出すようにした。
・実行開始時に、TmpDirの「*.$*」ファイルを削除するようにした。
・「comtxt.tmp」の各発言の行頭に次の行を入れるようにした。
HPの場合 *****log整理(HP:xxxxxxxx ) ファイル名 *****
PATIOの場合 *****log整理(PATIO:xxxxxxxx ) ファイル名 *****
フォーラムの場合 *****log整理(FORUM:xxxxxxxx MES:xx) ファイル名 *****
「xxxxxxxx」の部分は8文字で、左詰めで表示する。
「xx」の部分は2文字で、右詰めで表示する。
・内部形式の変更(comtree.tmp)
関係のある関数は sort1_sub2() makeIndex()。
1行目はフォーラム名。HP、PATIOの場合は設置者ID。
2行目はフォーラム名の行(NIFTYの形式)
3行目は会議室名の行
4行目は
>"%5d %5d %8ld %8ld %5d %5d %10ld\n"
| | | | | | ↓
| | | | | ↓ 発言日時
| | | | ↓ 発言の終了行
| | | ↓ 発言の開始行
| | ↓ 発言の終了バイト数
| ↓ 発言の開始バイト数
↓ コメント元番号
発言番号
5行目は発言のあったファイル名をパス名付きで書き出す。
6行目は標題の行を書き出す。(ツリー形式)
7行目は標題の行を書き出す。(発言番号の行。NIFTYの形式)
8行目は改行コードだけが入る。
・version 0.03h より作り直す。
-------------------------- ct003j --------------------------
1993.7.19
・st を size_t 型に変更。
・発言の標題をオンメモリで処理するようにした。
・メモリモデルをヒュージ型とした。
1993.7.19
・発言番号を long として処理するようにしたバージョン
-------------------------- ct003i --------------------------
1993.7.19
・発言番号を int として処理するようにしたバージョン
-------------------------- ct003h --------------------------
1993.7.18
・衆議院議員選挙の日。(関係ない)
・テスト用スイッチを追加。
「-u」「u」に続けて数字を書くと、そのレベルまでのツリーとする。
・FAPXのためのデータを出力する。ファイル名は「FAPXTREE.TMP」。
フォーラム名の場合:forum=<FROUM名>;
mes=<会議室番号>;
HPの場合 :hp=<ID>;
PATIOの場合 :patio=<ID>;
発言番号 :no=<発言番号>;
コメント元番号 :com=<コメント元番号>;
開始位置 :sb=<数>; ← バイト単位
sl=<数>; ← 行単位
発言のサイズ :eb=<数>; ← バイト単位
el=<数>; ← 行単位
発言日時 :date=<数>;
ファイル名 :file=<パス付きファイル名>;
標題 :title=<文字列>
・内部形式の変更
関係のある関数は sort1_sub2() makeIndex()。
1行目はフォーラム名。HP、PATIOの場合は設置者ID。
2行目はフォーラム名の行(NIFTYの形式)
3行目は会議室名の行
4行目は
>"%5d %5d %8ld %8ld %5d %5d %10ld\n"
| | | | | | ↓
| | | | | ↓ 発言日時
| | | | ↓ 発言の終了行
| | | ↓ 発言の開始行
| | ↓ 発言の終了バイト数
| ↓ 発言の開始バイト数
↓ コメント元番号
発言番号
5行目は発言のあったファイル名をパス名付きで書き出す。
6行目は標題の行を書き出す。
7行目は改行コードだけが入る。
1993.7.15
・「i」[インデックスからツリーを作る]を削除
・ツリー作成の際の不具合を修正。
・複数のCATLOG整理済の発言についてもツリーを作るようにした。
-------------------------- ct003g --------------------------
1993.7.15
・「-2」の時、同時に「-l」スイッチも設定してある場合はファイル名として処理す
るように修正。
・「comtree.txt」の出力形式を変更。
HP、PATIOの場合もフォーラムと同じ順にした。
1993.7.14
・「-2」mode における出力形式の変更。
TmpDirに下のファイルを作る。
フォーラムの会議室の発言:フォーラム名+$M数 数:1~9とA~K
HP の発言:設置者ID +$H0
PATIO の発言:設置者ID +$P0
TmpDirが設定されていない場合はカレントディレクトリに作られる。
1993.7.13
・新しいオプションの追加。
「-t」発言の本体を出力しないという指定。
1993.7.12
・sort1() を書き換える。この書換えによって調べる階層の深さをより深く出来るよ
うになった。
コメントの深さ LEVEL_COMMENT を 35 で定義。
・新しいオプションの追加。
「-d」画面上に表示していた標題等の行を表示しないようにするスイッチ。
実行環境にもよると思うが、約36%時間が短縮される。
-------------------------- ct003f --------------------------
1993.7.11
・0.03e の修正では無視された発言が表示されない。勿論、処理されない。
バグ修正。
-------------------------- ct003e --------------------------
1997.7.11
・コメント関係が深いと「stack overflow」エラーで中断してしまうバグ報告。
←Yama-chanより。
コメントの深さを LEVEL_COMMENT で定義。とりあえず 20 に設定してある。
これ以上深いレベルの関係は無視する。
-------------------------- ct003d --------------------------
1993.7.11
・comtree0.tmp という標題だけのファイルを作ることにした。
-------------------------- ct003c --------------------------
1993.7.10
・新しいオプションの追加。
「-2」:全てのフォーラム、HP、PATIOについて検索する。
・comtree.tmp は6行を基本とするように変更した。
1行目はフォーラム名の行
2行目は会議室名の行
3行目は
>"%5d %5d %8ld %8ld %5d %5d %10ld\n"
| | | | | | ↓
| | | | | ↓ 発言日時
| | | | ↓ 発言の終了行
| | | ↓ 発言の開始行
| | ↓ 発言の終了バイト数
| ↓ 発言の開始バイト数
↓ コメント元番号
発言番号
4行目は発言のあったファイル名をパス名付きで書き出す。
5行目は標題の行を書き出す。
6行目は改行コードだけが入る。
-------------------------- ct003b --------------------------
1993.7.4
・フォーラムの会議室の発言が整理できないバグ報告<Yama-chanさん
・オプションスイッチ「-v」の導入。但し、未公開バージョンのみ。
-------------------------- ct003a --------------------------
1993.7.4
発言の日時でソートを行っていないバグの報告。<Yama-chanさん
内部形式の行に追加。以下のようになる。
>"%5d %5d %8ld %8ld %5d %5d %10ld\n"
| | | | | | ↓
| | | | | ↓ 発言日時
| | | | ↓ 発言の終了行
| | | ↓ 発言の開始行
| | ↓ 発言の終了バイト数
| ↓ 発言の開始バイト数
↓ コメント元番号
発言番号
-------------------------- ct002e --------------------------
1993.6.28
・「comtree.tmp」ファイルには発言の標題のみを書き込むことにする。
いつでも復旧できるように #ifndef ONLY_HYOUDAI として書き込む部分を削除する。
・HPとPATIOに対応。ただし、チェックが不充分。
実行形式
ct -hi ID CATLOGディレクトリ名 TMPディレクトリ名
ct -hn ID CATLOGディレクトリ名 TMPディレクトリ名
ct -hf ID ログ・ファイルディレクトリ名 TMPディレクトリ名
実行形式
ct -pi ID CATLOGディレクトリ名 TMPディレクトリ名
ct -pn ID CATLOGディレクトリ名 TMPディレクトリ名
ct -pf ID ログ・ファイルディレクトリ名 TMPディレクトリ名
IDは、設置者のIDである。
PATIOはベタ指定も可。HPはベタ指定しても無視。
1993.6.27
・「comtree.tmp」の1行目の出力形式を固定長とした。
・ファイルの先頭からの行数と発言本体の行数を記録するようにした。
ただし、CATLOGのインデックスからコメントツリーを作った場合は入らない。
上2点については、次のようになる。
>"%5d %5d %8ld %8ld %5d %5d\n"
| | | | | ↓
| | | | ↓ 発言の終了行
| | | ↓ 発言の開始行
| | ↓ 発言の終了バイト数
| ↓ 発言の開始バイト数
↓ コメント元番号
発言番号
1行目は
発言番号、
コメント元番号、
ファイル中での位置(seek位置)、
発言のバイト数(標題の行の文字数も含みます)
発言の開始行
発言の終了行
-------------------------- ct002d --------------------------
1993.6.27
・「-f」や「-l」の場合、最初の発言がその番号よりも前の発言へのコメントであっ
た場合、正しく処理されないバグの修正。
・出力形式の変更。ファイル位置を、ファイル先頭からの行数にする。
>参考)mread(ファイル名[,メモ番号[,開始バイト位置[,読み込みバイト数]]])
あれ? これだとバイト数がいいんだけどなあ。とういことで、変更はなし。
・発言をファイルに書き出す。書き出すファイルを名は「comtxt.tmp」とする。
1993.6.26
・新しいオプションの追加。
「-l」で、InputDir名の所にファイル名を指定する。
これで、ファイルを指定してコメントツリーを作ることができるようになる。
-------------------------- ct002c --------------------------
1993.6.26
・-i で、指定のディレクトリに存在しない会議室番号を設定すると異常終了する。
「CATLOGで整理したファイルが見つかりません」と表示される。
・指定ディレクトリをカレントディレクトリとして指定するとサブ・ディレクトリの検索を行ってい
ない。「CATLOGで整理したファイルが見つかりません」と表示される。
・CATLOGのインデックス・ファイルにはあるのに整理したファイルが rename されたかで、
「MESxx_xx.TXT」の形になっていない場合、その発言は無視することにした。
(以前はエラーで終了)
1993.6.25
・指定のディレクトリに発言が見つからなかった時の終了処理を強化。
発言が見つからなかった場合は「comtree.tmp」というファイルは削除する(存在
しないようにする)
・CATLOGのインデックス・モードで「全体で1つ」を指定した場合の処理の強化。
単に、インデックスのあったディレクトリに「ディレクトリ\FORUM\MESxx_xx.TXT」というファイル
があるかどうかのチェックを行っているだけ。あればそれを発言ファイル名とする。
(超安易モード)
-------------------------- ct002b --------------------------
1993.6.24
発言のバイト数をファイルに書き出す部分を追加。
-------------------------- ct002a --------------------------
1993.6.23
処理の高速化を始めた。
ベタ・タイトル表示の場合、コメント・ツリー表示もすることにした。
この場合、「allover.tmp」というファイルにベタ・タイトルのデータを書き出し
ている。
-------------------------- ct001d --------------------------
1993.6.22
各表示の行頭に発言番号を表示することはやめにした。
-------------------------- ct001c --------------------------
1993.6.21
ベタタイトル表示モードの追加。
実行形式
ct -i1 フォーラム名 会議室番号 CATLOGディレクトリ名 TMPディレクトリ名
ct -n1 フォーラム名 会議室番号 CATLOGディレクトリ名 TMPディレクトリ名
ct -f1 フォーラム名 会議室番号 ログ・ファイルディレクトリ名 TMPディレクトリ名
これは、コノミさんの提案による。
発言番号の表示を必ず5桁になるようにした。
-------------------------- ct001b --------------------------
1993.6.21
発言番号とコメント元番号の桁数を5文字とした。
各行の最初に5桁で発言番号を入れることにした。
これは、コノミさんの提案による。
-------------------------- ct001a --------------------------
1993.6.21
Version 0.01a 完成。内部公開。
1993.6.18
・作成開始。
・仕様
実行形式
ct -i フォーラム名 会議室番号 CATLOGディレクトリ名 TMPディレクトリ名
この場合、CATLOGのインデックスファイルを参照する。
ct -n フォーラム名 会議室番号 CATLOGディレクトリ名 TMPディレクトリ名
CATLOGで整理したファイルだけを参照する。
ct -f フォーラム名 会議室番号 ログ・ファイルディレクトリ名 TMPディレクトリ名
生のログ・ファイルがあるものとして処理を行う。
実行後
「TMPディレクトリ名」の下に「comtree.tmp」というファイルを作る。
NIFPが作るようなコメントツリーの順にデータを書き出す。
そのファイルの内容は、4行が1セットになる。
1行目は
発言番号、
コメント元番号、
ファイル中での位置(seek位置)、
発言のバイト数(標題の行の文字数も含みます)
発言の日時
を順に書き出す。
2行目は発言のあったファイル名をパス名付きで書き出す。
3行目は標題の行を書き出す。
4行目は改行コードだけが入る。
なお、TMPディレクトリには作業用として「$ct0.tmp」「$ct1.tmp」「$ct2.tmp」
等のファイルが作られる。
作業用ファイルは処理が終わると削除される。
・処理の内容
CATLOGのインデックス・ファイルの構造
>16 64 9306150913 FTOWNS1 64559 62
>16 65 9306151935 FTOWNS1 66412 0
>16 66 9306152121 FTOWNS1 67287 64
>16 67 9306152157 FTOWNS1 68438 62
↑ ↑ ↑ ↑ ↑ ↑
| | | | | コメント元の発言番号(A)
| | | | MESxx_xx.TXTファイルでの発言の開始位置(B)
| | | フォーラム名(C)
| | 発言日時(D)
| 発言番号(E)
会議室番号(F)
1.フォーラム名と会議室番号を入力する。(FAPX)
2.CATLOGのインデックスファイルから会議室番号(F)と発言番号
(E)と発言の開始位置(B)とコメント元発言番号(A)を抽出する。
抽出した結果をファイルに書き出す。書き出す内容は、
(1)抽出元ファイル CATLOGの場合だと、MESxx_xx.TXTのファイル
(2)上の A ~ F の値
3.NIFPがやっているような順にデータを並び替える。
4.並び替えたデータをファイルに書き出す。
5.4で作ったファイルを順に参照しながら(特にBを参照する)発言番号
の行を画面に表示していく。あるいは、別のファイルに書き出す。
6.FAPXは、5のデータを表示してマウスのダブルクリックから、指定
の行--先頭から何行目か---を上のリアルプログラムに渡す。
7.リアルプログラムでは、指定された行数と、4のファイルを参照して、
指定発言を別のファイルに切り出す。
8.再びFAPXは、そのファイルをメモ画面に表示してRESを書く。
普通のログファイルからもコメントツリーを作れるようにする。
以下の人々が、このプログラムの作成に協力してくれました。
ここに紹介して感謝の念を表したいと思います。
PEE01244 Yama-chan さん
PFG02442 <Nakatani> さん
QFH02666 『コノミ』 さん
# DIVIDE_END
/* DIVIDE_START=check.c */
/*
コメントツリー作成プログラム check.c
作 : 山先(NIFTY-ID:GHH01217)
*/
#include "ct.h"
static int isCATLOGFile( const char *f_name )
{
int num;
char *p1 , *p2;
FILE *fpi;
/* 初期化 */
*ForumNameLine = '\0';
for ( num=0; num<21; num++ ) *KNL[ num ] = '\0';
if ( ( fpi=fopen( f_name , "r" ) ) == NULL ) { /* 起こり得ないエラー */
er_open( f_name, 0, "isCATLOGFile" );
};
fgets( str , LINE , fpi );
num = 0;
isCATLOGFileSw = StartMesSw = FALSE;
p2 = str;
if ( strncmp( str , "FORUM:" , 6 ) == 0 ) {
p1 = str + 6;
while ( isalnum( *p1 ) ) *p2++ = *p1++; *p2 = '\0';
while ( *p1 == ' ' ) p1++;
if ( strncmp( p1 , "MES:" , 4 ) == 0 ) {
p1 += 4; /* skip 'MES:' */
num = atoi( p1 );
StartMesSw = TRUE;
} else if ( strncmp( p1 , "LIB:" , 4 ) == 0 ) {
p1 += 4; /* skip 'LIB:' */
LibNum = atoi( p1 );
num = LIB;
};
if ( strlen( str ) <= 8 && num != 0 ) {
strcpy( ForumName , str ); MesNum = num;
};
} else if ( strncmp( str , "MAIL:" , 5 ) == 0 ) {
p1 = str + 5;
while ( isalnum( *p1 ) ) *p2++ = *p1++; *p2 = '\0';
if ( isIDname( str ) == YES ) {
strcpy( ForumName , str ); MesNum = num = MAIL;
set_ForumNameLine( MAIL );
};
} else if ( strncmp( str , "HP:" , 3 ) == 0 ) {
p1 = str + 3;
while ( isalnum( *p1 ) ) *p2++ = *p1++; *p2 = '\0';
if ( isIDname( str ) == YES ) {
strcpy( ForumName , str ); MesNum = num = HP;
set_ForumNameLine( HP );
};
} else if ( strncmp( str , "PATIO:" , 6 ) == 0 ) {
p1 = str + 6;
while ( isalnum( *p1 ) ) *p2++ = *p1++; *p2 = '\0';
if ( isIDname( str ) == YES ) {
strcpy( ForumName , str ); MesNum = num = PATIO;
set_ForumNameLine( PATIO );
};
} else if ( strncmp( str , "BILL:BILL" , 9 ) == 0 ) {
strcpy( ForumName , "BILL" ); MesNum = num = BILL;
} else if ( strncmp( str , "COLLECT_ID:" , 11 ) == 0 ) {
p1 = str + 11;
while ( isalnum( *p1 ) ) *p2++ = *p1++; *p2 = '\0';
if ( isIDname( str ) == YES ) {
strcpy( ForumName , str ); MesNum = num = COLLECT_ID;
};
} else if ( strncmp( str , "ALL-MAIL" , 8 ) == 0 ) {
strcpy( ForumName , "ALL-MAIL" ); MesNum = num= ALL_MAIL;
} else if ( strncmp( str , "CLIP" , 4 ) == 0 ) {
strcpy( ForumName , "CLIP" ); MesNum = num = CLIP;
} else {
fclose( fpi ); return( 0 );
};
if ( num != 0 ) {
isCATLOGFileSw = TRUE;
if ( num > 0 ) {
fgets( ForumNameLine, 80, fpi );
without_crlf( ForumNameLine );
fgets( KNL[0], 80, fpi );
without_crlf( KNL[0] );
};
};
fclose( fpi );
return( num );
}
static int
Check1FileTRUE( const char *f_name , const char *ff_name )
{
const char *p;
FILE *fp;
p = last_comma( ff_name );
/********************************/
/* ファイル指定でチェックしない */
/* 複数ファイル検索の時である */
/********************************/
if ( isCATLOGFileSw != 0 ) {
/****************************************/
/* CATLOGで整理したファイルである */
/****************************************/
if ( doOnlyCurrentCATLOGFile == TRUE ) {
if ( MesNum <= 20 ) {
if ( matchstr( "MES%%_00.TXT", ff_name ) == FALSE
) {
return( FALSE );
};
} else {
if ( matchstr( "$$$%%%%%.ML0", ff_name ) == FALSE
&& matchstr( "$$$%%%%%.HP0", ff_name ) == FALSE
&& matchstr( "$$$%%%%%.PA0", ff_name ) == FALSE
&& matchstr( "LIB%%.TXT", ff_name ) == FALSE
) {
return( FALSE );
};
};
};
} else {
/******************************/
/* 普通の生ログファイルである */
/* 拡張子を調べる */
/******************************/
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "Check1FileTRUEです %s の拡張子を調べます\n", f_name );
};
#endif
if ( p != ff_name ) {
p++;
for( sayNum=0; sayNum<MAX_ATTR; sayNum++ ) {
if ( strcmp( p, attr[sayNum] ) == 0 ) return( FALSE );
};
for( sayNum=0; sayNum<MAX_ATTR1; sayNum++ ) {
if ( strcmp( p, attr1[sayNum] ) == 0 ) return( FALSE );
};
/* 1993.8.4 変更 */
if ( strncmp( p, "$F", 2 ) == 0 ) return( FALSE );
};
};
/****************************************/
/* 検索するファイルサイズの合計値の計算 */
/****************************************/
if ( MaxFileSizeSw == TRUE ) {
/* ↓ ファイルサイズを調べるもっと良い方法は? */
SearchFileSize += GetFileSize( f_name );
/* 規定値より大きくなる時は ファイルを検索しない */
if ( SearchFileSize > MaxSearchFileSize ) return( FALSE );
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "%8ld\n", SearchFileSize );
};
#endif
};
return( TRUE );
}
static void OverIdxFile( char *forum, int mes )
{
char *p, sub[ 4 ];
sprintf( FileName, "%s%s.$", TmpDir, forum );
switch( mes ) {
case BILL: p = "B0"; break; /* 利用料金情報 */
case CLIP: p = "C0"; break; /* クリッピングサービス */
case HP: p = "H0"; break; /* Home Party */
case LIB: p = "L0"; break; /* LIB */
case MAIL: p = "M0"; break; /* 電子メール */
case PATIO: p = "P0"; break; /* PATIO */
case NEW: p = "N0"; break; /* 「今週のお知らせ」 */
default: /* フォーラムの会議室である */
p = sub; *p++ = 'F';
if ( mes < 10 ) { *p = '0' + mes;
} else { *p = 'A' - 10 + mes;
};
*(++p) = '\0';
p = sub;
break;
};
strcat( FileName, p );
}
int OverIdxSort( const struct IDX2 *p1 , const struct IDX2 *p2 )
{
/* 次の順序でソートする
(1) フォーラム名
(2) 会議室番号
(3) 発言日時
(4) 発言番号
*/
if(p1->ForumName !=p2->ForumName) return( p1->ForumName -p2->ForumName );
if ( p1->MesNum != p2->MesNum ) return( p1->MesNum - p2->MesNum );
if ( p1->MesNum == LIB ) {
/* LIB は発言番号 → 発言日時 の 順 */
if ( p1->SayNum != p2->SayNum ) return( p1->SayNum - p2->SayNum );
if ( p1->SayDate < p2->SayDate ) return( -1 );
if ( p1->SayDate > p2->SayDate ) return( 1 );
return( 0 );
} else {
if ( p1->SayDate == p2->SayDate ) return( p1->SayNum - p2->SayNum );
if ( p1->SayDate < p2->SayDate ) return( -1 );
if ( p1->SayDate > p2->SayDate ) return( 1 );
return( 0 );
};
}
void SortIdx2()
{
int m0, m1 ;
for ( m0 = 0; m0 < idx2P; m0++ ) {
if ( idx2[m0].MesNum == NEW ) {
sayNum = idx2[m0].SayNum;
for ( m1 = m0+1; m1 < idx2P ; m1++ ) {
if ( idx2[m1].MesNum != NEW ) break;
};
/* m0 ~ m1 が NEW の区間 */
HatsugenSu = m1; sortNEW( m0 );
m0 = m1 - 1; /* m0 を進める */
};
};
/* 次の順序でソートする
(1) フォーラム名
(2) 会議室番号
(3) 発言日時
(4) 発言番号
*/
qsort( (char *)idx2, idx2P, sizeof(struct IDX2), OverIdxSort );
}
void OverIdx()
{
int i, forum, mesNum;
SortIdx2();
OverIdxSw = TRUE;
forum = mesNum = -1;
for ( i = 0; i < idx2P ; i++ ) {
if ( forum != idx2[i].ForumName
|| mesNum != idx2[i].MesNum
) {
forum = idx2[i].ForumName;
mesNum = idx2[i].MesNum;
OverIdxFile( idxs[idx2[i].ForumName].name, idx2[i].MesNum );
if ( CT_fpo != NULL ) fclose( CT_fpo );
if ( ( CT_fpo = fopen( FileName, "a")) == NULL ) {
er_open( FileName, 1, "OverIdx" );
};
};
/* 1行目:フォーラム名と会議室番号を書き出す */
fprintf( CT_fpo, "%s %2d\n"
, idxs[idx2[i].ForumName].name
, idx2[i].MesNum
);
/* 2行目:ForumNameLine を書き出す */
fprintf( CT_fpo, "%s\n", idxs[idx2[i].ForumNameLine].name );
/* 3行目:会議室名の行を書き出す */
if ( idx2[i].KNL < 0 ) {fprintf(CT_fpo,"\n" );
} else { fprintf(CT_fpo,"%s\n",idxs[idx2[i].KNL].name );
};
/* 4行目:ファイル名を書き出す */
/* 5行目:発言に関するデータを書き出す */
long_to_date( MesNum, str, idx2[i].SayDate );
fprintf( CT_fpo, "%s\n%5d %5d %8ld %8ld %5d %5d %s\n"
, idxs[idx2[i].FileName].name
, idx2[i].SayNum
, idx2[i].ComNum
, idx2[i].seek
, idx2[i].blen
, idx2[i].gyou
, idx2[i].glen
, str
);
/* 6行目:発言の題名 */
fprintf( CT_fpo, "%s\n", idx2[i].HyoudaiLine );
};
fclose( CT_fpo ); CT_fpo = NULL;
idx2P = 0;
}
int isIdxS( const char *str )
{
int i;
struct IDXS *idxsp;
for ( i=0, idxsp=idxs ; i<idxsP ; i++, idxsp++ ) {
if ( strcmp( idxsp->name, str ) == 0 ) return( i );
};
if ( idxsP >= max_idxs ) {
/* idxs があふれた場合の処理 */
OverIdx(); idxsP = 0; idxsp = idxs;
};
strcpy( idxsp->name, str );
idxsP++;
return( i );
}
static void Check1FileSave( const char *f_name, long seek )
{
int i;
if ( idx2P >= max_idx2 ) {
/* idx2 があふれた場合の処理 */
OverIdx();
};
if ( *ForumName == '\0' ) strcpy( ForumName, "UNKNOWN" );
idx2[idx2P].ForumName = isIdxS( ForumName );
idx2[idx2P].MesNum = MesNum;
idx2[idx2P].SayNum = sayNum;
idx2[idx2P].SayDate = sayDate;
/* 登録済のデータ? */
/* NEW は全部ロードする */
if ( MesNum != NEW ) {
for ( i=0; i<idx2P; i++ ) {
if ( idx2[i].ForumName == idx2[idx2P].ForumName
&& idx2[i].MesNum == idx2[idx2P].MesNum
&& idx2[i].SayNum == idx2[idx2P].SayNum
&& idx2[i].SayDate == idx2[idx2P].SayDate
) return;
};
};
idx2[idx2P].KNL = idx2[idx2P].ForumNameLine = isIdxS( ForumNameLine );
if ( 1 <= MesNum && MesNum <= 20 ) {
if (*KNL[MesNum]!='\0') { idx2[idx2P].KNL = isIdxS( KNL[ MesNum ] );
} else { idx2[idx2P].KNL = isIdxS( KNL[ 0 ] );
};
} else if ( MesNum == PATIO ) { idx2[idx2P].KNL =isIdxS( KNL[ 1 ] );
};
idx2[idx2P].FileName = isIdxS( f_name );
idx2[idx2P].ComNum = comNum;
idx2[idx2P].seek = seek;
idx2[idx2P].blen = pool_seek_ichi - seek;
idx2[idx2P].gyou = gyou;
idx2[idx2P].glen = LineNumber - gyou;
idx2[idx2P].ahure = 0x00;
strcpy(idx2[idx2P].HyoudaiLine, HyoudaiLine );
idx2P++;
HatsugenSu++;
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "%s %2d %5d %5d %5ld %5ld %s ○\n"
, f_name /* ファイル名 */
, MesNum, sayNum, comNum, seek
, pool_seek_ichi - seek
, str
);
};
#endif /* VERIFY */
}
void Check1File( const char *f_name , const char *ff_name )
{
int sw;
long seek;
if ( kbhit() ) {
sw = getch(); ungetch( sw ); if ( sw == ESC ) exit( 1 );
};
/* CATLOGのインデックス・ファイルを無視する 1993.8.2 追加 */
if ( strcmp( ff_name, IDX_FILE_NAME ) == 0 ) return;
LibNum = 0;
strcpy( ForumName , "UNKNOWN" );
/* CATLOGで整理したファイル? */
/* もしそうなら
ForumNameLine
KNL[ 0 ~ 20 ]
が初期化後・設定される
*/
sw = isCATLOGFile( f_name );
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "Check1Fileです %s %2d \n", ForumName, MesNum );
};
#endif
/* COLLECT_ID は無視する 1993.8.2 追加 */
if ( sw == COLLECT_ID ) return;
/****************************************/
/* 検索するファイルについてチェックする */
/****************************************/
/* ファイル指定でチェックする? */
if ( doFrom1LOGFile == FALSE ) {
if ( Check1FileTRUE( f_name, ff_name ) == FALSE ) return;
};
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "フォーラム名は<%s>で、会議室番号は %2d です\n"
, ForumName, MesNum
);
printf( "Check1Fileです %s の内容を調べます\n", f_name );
};
#endif
/******************/
/* 発言の探索開始 */
/******************/
if ( Display == TRUE ) {
printf( "%-8s\t%8ld Bytes\n", f_name, GetFileSize(f_name) );
};
if ( initial_check_pool( f_name ) == TRUE ) {
sw = FALSE; /* 発言がない場合もある */
GET_LINE2 ; /* 先読み 1993.8.12 追加:バグ修正 */
forever {
CPDS = PSP; seek = pool_seek_ichi;
/* 発言開始の行? */
/* もしあれば、
HyoudaiLine
hatsugenDate
がセットされる
*/
if ( isHPMes( ) != TRUE
&& isMAILMes( ) != TRUE
&& isPATIOMes( ) != TRUE
&& isFORUMMes( ) != TRUE
&& isNEWMes( ) != TRUE
&& isCLIPMes( ) != TRUE
&& isBILLMes( ) != TRUE
&& isLIBMes( ) != TRUE
) {
GET_LINE2 break;
continue;
};
if ( MesNum == LIB ) { gyou = LineNumber - 3;
} else { gyou = LineNumber;
};
if ( Display == TRUE ) {
sw = TRUE; /* 発言があったというしるし */
present_str_copy( str );
printf( "%-78s", str ); putchar( 0x0d );
};
/* 発言の最後を見つける */
do {
CPDS = PSP;
GET_LINE2 break;
} while ( isMesEnd() == NO );
Check1FileSave( f_name, seek );
if ( MesNum == LIB ) {
LibNum = 0;
MesNum = 0;
};
};
end_check_pool();
if ( Display == TRUE ) {
if ( sw == TRUE ) putchar( 0x0a ); /* LF */
};
} else {
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "<%s>というファイルが見つかりません\n", f_name );
};
#endif
};
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "フォーラム名は<%s>です\n", ForumName );
printf( "Check1Fileでした %s の内容を調べました\n", f_name );
};
#endif
}
/* DIVIDE_END */
/* DIVIDE_START=file.c */
/*
GUI-CATLOG補助プログラム file.c
1993.5.10
このファイルでは、ファイルの入出力の高速化の為の処理を定義している。
*/
#include "ct.h"
/* 広域変数 */
char *catlog_pool=NULL;
char *CPDS; /* check pool delete start */
char *LSP , *PSP , *NSP;
int LSL , PSL , NSL;
long pool_seek_ichi; /* ファイルの中での位置 */
/* 局所変数 */
static char *sentinel; /* 文章の最後 */
static FILE *pool_fpi = NULL;
static char *check_sentinel , *check_head , *pool_end;
static int catlog_fread_char;
static int catlog_fread_char_sw = NO;
static void delete_line( char *start , char *end )
{
long len;
if ( start == end ) return;
if ( start == NULL ) return;
if ( end == NULL ) return;
if ( start < catlog_pool || end < catlog_pool ) {
sprintf(str,"delete_line 管理領域を破壊します<%ld> <%ld>",
start - catlog_pool,
end - catlog_pool
);
puts( str ); exit( 1 );
};
len = end - start;
memmove( start , end , check_sentinel - end );
/********************/
/* ポインタ類の更新 */
/********************/
if ( start < LSP && LSP < end ) { LSP = start;
} else if ( end <= LSP ) { LSP = LSP - len;
};
if ( start < PSP && PSP < end ) { PSP = start;
} else if ( end <= PSP ) { PSP = PSP - len;
};
if ( start < NSP && NSP < end ) { NSP = start;
} else if ( end <= NSP ) { NSP = NSP - len;
};
if ( start < check_head && check_head < end ) { check_head = start;
} else if ( end <= check_head ) { check_head = check_head - len;
};
if ( start < sentinel && sentinel < end ) { sentinel = start;
} else if ( end <= sentinel ) { sentinel = sentinel - len;
};
if ( start < CPDS && CPDS < end ) { CPDS = start;
} else if ( end <= CPDS ) { CPDS = CPDS - len;
};
}
static long catlog_fread( char *pool1 )
{
int c, sw;
long len1, len2;
sw = 0;
if ( catlog_fread_char_sw != NO ) {
sw = 1;
*pool1++ = catlog_fread_char;
catlog_fread_char_sw = NO;
};
len1 = check_sentinel - pool1; /* ロードするバイト数 */
if ( len1 < 0 ) {
puts("catlog_fread ちゃんと領域を確保してね" ); exit( 1 );
};
if ( pool1 < catlog_pool ) {
sprintf(str,"catlog_fread 管理領域を破壊しますよ。<%ld> ",
pool1 - catlog_pool
);
puts( str ); exit( 1 );
};
/* ロードしたバイト数 */
len2 = fread( pool1 , sizeof(char) , len1 , pool_fpi );
if ( len2 < len1 ) {
c = fgetc( pool_fpi ); /* set EOF flag */
if ( c != EOF ) {
catlog_fread_char = c;
catlog_fread_char_sw = YES;
} else {
catlog_fread_char_sw = NO;
};
};
#ifdef TEST
printf("%ldバイトロードしたよ。\n" , len2 + sw );
#endif
sentinel = pool1 + len2;
return ( len2 + sw );
}
static long load_sentinel()
{
long len;
if ( catlog_pool <= CPDS ) {
delete_line( catlog_pool , CPDS );
};
if ( sentinel == check_sentinel ) {
puts( "確保した作業領域より発言の方が大きいので、"
"データをロードできません。"
"\n処理を終了します"
);
exit( 1 );
};
len = catlog_fread( sentinel );
return( len );
}
static char *set_next_str()
{
long len;
NSL= 0; NSP= check_head;
if ( check_head == NULL ) return( PSP );
if ( check_head >= sentinel ) {
if ( feof( pool_fpi ) != 0 ) { /* EOF */
NSP = check_head = NULL; return( PSP );
};
/* 処理済みの行を削除 */
len = load_sentinel();
/* 以下は必要ないが……… */
if ( len == 0L ) { /* EOF */
NSL = check_head - NSP; check_head = NULL; return( PSP );
};
};
forever {
if ( *check_head == 0x0d ) {
check_head++;
if ( *check_head == 0x0a ) check_head++;
break;
};
check_head++;
if ( check_head >= sentinel ) {
if ( feof( pool_fpi ) != 0 ) break; /* EOF */
/* 処理済みの行を削除 */
len = load_sentinel();
/* 以下は必要ないが……… */
if ( len == 0L ) { /* EOF */
NSL = check_head - NSP; check_head = NULL; return( PSP );
};
};
};
NSL = check_head - NSP;
return( PSP );
}
/********************/
/* ポインタ群の更新 */
/********************/
char *catlog_fgets()
{
LineNumber++;
/* ファイルの中での位置 */
if ( NSP != NULL && PSP != NULL ) pool_seek_ichi += (long)(NSP - PSP);
LSL = PSL; LSP = PSP;
PSL = NSL; PSP = NSP;
#if VERIFY == YES
if ( verify == TRUE ) {
present_str_print();
};
#endif
return( set_next_str() );
}
#if VERIFY == YES
void present_str_print()
{
int c;
c = *(PSP + PSL - 2 ); *(PSP + PSL - 2 ) = '\0';
puts( PSP ); *(PSP + PSL - 2 ) = c;
}
void next_str_print()
{
int c;
c = *(NSP + NSL - 2 ); *(NSP + NSL - 2 ) = '\0';
puts( NSP ); *(NSP + NSL - 2 ) = c;
}
#endif
/**********************************/
/* catlog_pool[] の領域を確保する */
/**********************************/
void pool_malloc( )
{
int sw;
long max, min, tmp, tuika, size, fsize;
fsize= (long)MAX_BUFSIZE;
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "pool_malloc(%ld) です",fsize);
printf( "未使用メモリーは %u バイトあります\n",coreleft() );
};
#endif
/* 1993.3.24 JINX さんよりバグ報告
* fsize が小さいと 0x0d の後ろの 0x0a を追加できなくハングする
* 以下の1行追加
*/
if ( fsize < 20 ) fsize = ( fsize + 10 ) * 10;
tuika = 10;
size = ( fsize + tuika ) * sizeof( char ) ;
if ( ( catlog_pool = (char *)malloc( size )) != NULL){
check_sentinel = catlog_pool + fsize;
pool_end = check_sentinel + tuika;
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "%ld → %ld バイトを確保しました\n" , fsize , size );
};
#endif
return;
};
max = fsize; min = 0; tmp = ( max - min ) / 2 + min;
sw = FALSE;
while ( sw == FALSE ) {
size = ( tmp + tuika ) * sizeof( char ) ;
if( (catlog_pool = (char *)malloc(size)) == NULL ) {
max = tmp;
} else {
min = tmp; free( catlog_pool );
};
tmp = ( max - min ) / 2 + min;
if ( tmp < 1 ) er_memory( "pool_malloc" );
if ( max == min || max - 1 == min ) sw = TRUE;
};
catlog_pool = (char *)malloc( size );
check_sentinel = catlog_pool + tmp;
pool_end = check_sentinel + tuika;
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "%ld → %ld バイトを確保しました\n" , fsize , size );
};
#endif
}
/************************************/
/* FileName のオープンと領域の確保 */
/************************************/
int initial_check_pool( const char *FileName )
{
long fsize , fsize2;
if ( pool_fpi != NULL ) {
puts("プログラムのバグです initial_check_pool を2重に呼んでいます");
exit( 1 );
};
fsize = GetFileSize( FileName );
if ( fsize <= 0L ) return( FALSE );
check_head = catlog_pool;
CPDS =
LSP = PSP = NSP = catlog_pool;
LSL = PSL = NSL = LineNumber = 0;
catlog_fread_char_sw = NO;
pool_seek_ichi = 0L; /* ファイルの中での位置 */
if ( ( pool_fpi = fopen( FileName, "rb" ) ) == NULL ) {
er_open( FileName, 0, "initial_check_pool");
};
if ( ( fsize2 = catlog_fread( catlog_pool ) ) <= 0 ) {
printf("'initial_check_pool'でファイル<%s>をロードできません",
FileName
);
exit( 1 );
};
if ( fsize == fsize2 ) fgetc( pool_fpi ); /* set EOF flag */
set_next_str();
return( TRUE );
}
/*****************************/
/* catlog_poolを解放して終了 */
/*****************************/
void end_check_pool()
{
if ( catlog_pool != NULL ) {
fclose( pool_fpi ); pool_fpi = NULL;
} else {
puts( "領域を確保していないのに解放しようとしています" );
exit( 1 );
};
}
static char crlf[ 3 ] = { 0x0d , 0x0a , '\0' };
/****************************************************
CT では不要。
long catlog_fwrite( FILE *fpo )
{
long len;
if ( PSP == NULL ) {
len = fwrite( CPDS, sizeof(char), sentinel - CPDS, fpo );
if ( *(sentinel - 1 ) != 0x0a ) fwrite(crlf, sizeof(char), 2, fpo);
} else {
len = fwrite( CPDS, sizeof(char), PSP - CPDS, fpo );
if ( *(PSP - 1 ) != 0x0a ) fwrite(crlf, sizeof(char), 2, fpo);
};
return( len );
}
*****************************************************/
void catlog_fprintf( const char *targ , FILE *fpo )
{
int len;
len = strlen( targ );
if ( len != 0 ) fwrite( targ , sizeof(char) , len , fpo );
fwrite( crlf , sizeof(char) , 2 , fpo );
}
void CT_fcopy( FILE *fpi, long size, FILE *fpo)
{
long len;
if ( pool_fpi != NULL ) {
puts( "CT_fcopy の機能は initial_check_pool と同時に使えません" );
exit( 1 );
};
if ( size < 0L ) {
/* ファイル末まで copy */
forever {
/* ロードしたバイト数 */
len = fread( catlog_pool, 1, check_sentinel - catlog_pool, fpi);
if ( len <= 0L ) break;
fwrite( catlog_pool, 1, len, fpo);
};
} else {
while ( size > 0L ) {
/* ロードしたバイト数 */
len = fread( catlog_pool, 1, check_sentinel - catlog_pool, fpi);
/* ファイル末 */
if ( len <= 0L ) break;
if ( len < size ) {
/* ロードしたバイト数が size より小さい場合 */
fwrite( catlog_pool, 1, len, fpo);
} else {
/* ロードしたバイト数が size より大きい場合 */
fwrite( catlog_pool, 1, size, fpo);
};
size -= len;
};
};
}
long GetFileSize( const char *FileName )
{
FILE *fpi;
long res;
if ( ( fpi = fopen( FileName, "r" ) ) == NULL ) return( 0L );
fseek( fpi, 0L, SEEK_END );
res = ftell( fpi );
/*
res = filelength( fileno( fpi ) );
*/
fclose(fpi);
return( res );
}
/* DIVIDE_END */
/* DIVIDE_START=lib.c */
/*
コメントツリー作成プログラム lib.c
作 : 山先(NIFTY-ID:GHH01217)
*/
#include "ct.h"
int isLIBLine()
{
if ( PSL < 40 ) return( NO );
/* 0 1 2 3 4 */
/* 123456789 123456789 123456789 123456789 */
if ( matchstr( "???% $$$%%%%% %%/%%/%% ??????% ???% ? ?",PSP) != TRUE ) {
return( NO );
};
return( YES );
}
/*****************************************************
static int isLIBIchiran()
{
if ( PSL < 29 ) return( NO );
if ( matchstr( "???% ???% (???%) %%/%% ?",PSP) != TRUE ) {
return( NO );
};
return( YES );
}
*******************************************************/
int isLIBMes()
{
int libNum;
int line;
FILE *fpo;
if ( isCATLOGFileSw == TRUE
&& MesNum == LIB
) {
while ( isLIBLine() != YES ) {
CPDS = PSP; GET_LINE2 break;
};
sayNum = LibNum; /* 発言番号 */
comNum = 0; /* コメント元番号 */
set_ForumNameLine( LIB );
set_hatsugen_date( LIB, PSP, str );
sayDate = date_to_long( LIB, str );
/* 題名のセット */
set_hyoudaiName( LIB );
return( TRUE );
};
if ( matchstr( ">LIB ", PSP ) == TRUE
|| matchstr( ">lib ", PSP ) == TRUE
) {
LibNum = atoi( PSP + 6 );
#if VERIFY == YES
if ( verify == TRUE ) {
printf( ">LIB %d があったぞ~\n", LibNum );
};
#endif
return( FALSE );
};
/* 123456789 123456789 123456789 123456 */
if ( matchstr("番号 総数 登録済 最新 ライブラリ名", PSP )==TRUE ) {
LibNum = 0;
SaveTmpKaigishitsuNameLine( LIB );
return( FALSE );
};
if ( matchstr(
"データライブラリ (1:データ一覧 2:検索"
/*
" 3:アップロード(無料) 4:ダウンロード E:終了)"
*/
, PSP
) != TRUE
) return( FALSE );
/* ここから LIB の処理 */
libNum = atoi( LSP + 2 );
if ( LibNum == 0 ) {
if ( libNum != 0 ) { LibNum = libNum;
} else { LibNum = 9999;
};
};
GET_LINE2 return( FALSE );
/* ↓ FAPX でオートでダウンした場合 */
if ( matchstr( ">DIR", PSP ) != TRUE
&& matchstr( ">1", PSP ) != TRUE
) return( FALSE );
GET_LINE2 return( FALSE );
if ( matchstr(
"番号 ID 登録日付 バイト 参照 データ名"
, PSP
) != TRUE
) return( FALSE );
GET_LINE2 return( FALSE );
if ( isLIBLine() != YES ) return( FALSE );
MesNum = LIB;
sayNum = (long)LibNum; /* 発言番号 */
comNum = 0; /* コメント元番号 */
set_ForumNameLine( LIB );
set_hatsugen_date( LIB, PSP, str );
sayDate = date_to_long( LIB, str );
/* 題名のセット */
set_hyoudaiName( LIB );
return( TRUE );
}
/* DIVIDE_END */
/* DIVIDE_START=load.c */
/*
コメントツリー作成プログラム load.c
作 : 山先(NIFTY-ID:GHH01217)
*/
#include "ct.h"
void Copy1Say( long seek, long mojiSu )
{
int sw;
if ( kbhit() ) {
sw = getch(); ungetch( sw ); if ( sw == ESC ) exit( 1 );
};
if ( *FileNameSub == '\0'
|| strcmp( FileNameSub , FileName ) != 0
) {
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "Copy1Say です %s を新たにオープンします\n", FileName );
};
#endif
if ( CT_fpiText != NULL ) fclose( CT_fpiText );
if ( ( CT_fpiText = fopen( FileName, "rb" ) ) == NULL ) {
er_open(FileName,0, "Copy1Say");
};
strcpy( FileNameSub, FileName );
#if VERIFY == YES
} else {
if ( verify == TRUE ) {
printf( "Copy1Say です %s からそのまま発言本体を得ます\n"
, FileName
);
};
#endif
};
fseek( CT_fpiText, seek, SEEK_SET);
CT_fcopy( CT_fpiText, mojiSu, CT_fpoText);
}
static int loadSubSw;
static int commentLevel;
int loadSub( FILE *fpi )
{
char *p;
int glen;
long seek, blen;
/* フォーラム名の行 */
if ( fgets( ForumNameLine, 80, fpi ) == NULL ) return( FALSE );
/* 発言に関するデータ */
if ( fgets( str, LINE, fpi ) == NULL ) return( FALSE );
sscanf( str, "%5d %5d %8ld %8ld %5d %5d %10s %2d"
, &sayNum , &comNum , &seek , &blen
, &gyou , &glen , str , &CommentLevel
);
/* 終了? */
if ( CommentLevel <= commentLevel ) return( FALSE );
if ( strncmp( ForumNameLine, "CHANGE:", 7 ) == 0 ) { loadSubSw = FALSE;
} else {
/* TXF 用の行を出力する? */
if ( loadSubSw == FALSE
|| strncmp( ForumNameLine + 15, "LIB:", 4 ) == 0
) { /* この行を書き出す */
without_crlf( ForumNameLine );
catlog_fprintf( ForumNameLine, CT_fpoText ); loadSubSw = TRUE;
};
};
/* ファイル名 */
if ( fgets( str, LINE, fpi ) == NULL ) return( FALSE );
without_crlf( str );
if ( strlen( str ) > MAX_FILENAME_LEN ) {
str[ MAX_FILENAME_LEN -1 ] = str[ MAX_FILENAME_LEN -2 ] = '\0';
};
strcpy( FileName, str );
/* commentLevel の調整 */
if ( commentLevel == -999 ) { /* 第1発言の場合 */
p = ForumNameLine;
if ( strncmp( p, "CHANGE:", 7 ) == 0 ) p += 7;
if ( strncmp( p, "FORUM", 5 ) != 0
&& strncmp( p, "PATIO", 5 ) != 0
) { commentLevel = -1;
} else { commentLevel = CommentLevel;
};
};
/* 発言の本体をファイルに書き出す? */
if ( CommentLevel >= 0 ) Copy1Say( seek, blen );
return( TRUE );
}
/* line が comtree0.tmp の行数を表す */
void load( int line )
{
int i ;
FILE *fpi;
/* comtree.tmp ファイルのオープン */
set_tmp_file_name( COMTREE_TMP_FILE, FileName );
if ( ( fpi = fopen( FileName, "r" ) ) == NULL ) return;
/* comtxt.tmp ファイルのオープン */
set_tmp_file_name( COMTXT_TMP_FILE, FileName );
if ((CT_fpoText=fopen(FileName,"wb"))==NULL) er_open(FileName,1,"load");
/* 指定の部分以前を読み飛ばす */
line = ( line - 1 ) * 3 ; /* comtree.tmp の行数 */
for ( i = 0; i < line ; i++ ) fgets( str, LINE, fpi );
/* 最初の発言について処理する */
*FileNameSub = '\0'; CT_fpiText = NULL;
loadSubSw = FALSE; commentLevel = -999; loadSub( fpi );
forever {
if ( loadSub( fpi ) == FALSE ) break;
};
fclose( fpi );
fclose( CT_fpiText );
fclose( CT_fpoText );
/* ここから直性終了する */
exit( 0 );
}
/* DIVIDE_END */
/* DIVIDE_START=main.c */
/*
コメントツリー作成プログラム main.c
作 : 山先(NIFTY-ID:GHH01217)
*/
#define MAIN 1
#include "ct.h"
#include <process.h>
char *Version = VERSION;
static void useage()
{
printf(
" コメントツリー作成プログラム\t\t%s\n\t\t\t\t\tVersion=%s"
" by .. GHH01217 山先\n\n"
, FileName /* 起動ドライブが入っている */
, Version
);
puts(
"\t使い方:ct [-options] [-o OutDir名] InputDir名 or File名\n"
);
puts(
" ↓: option ↓: デフォルト\n"
#if VERIFY == YES
" ★★ 下の2つのオプションは非公開のオプションです ★★\n"
" コメントレベルの深さ → u : デフォルトで U数 : 数レベルまで\n"
" 動作状態を表示 → v : しない V : する\n"
"\n"
" ★★ ここから下が公開オプションです ★★\n"
#endif
" CATLOGで整理したファイル → a : 全てのファイルを検索 A : カレント・ファイルのみ検索\n"
" 標題等を画面に → d : 表示する D : 表示しない\n"
" 検索するファイルのサイズ → f : サイズで中断しない F数 : 数Kバイトまで検索\n"
" サブ・ディレクトリのファイルを → r : 検索する R : 検索しない\n"
" 発言の本体を → t : 出力する T : 出力しない\n"
" 標題は → 2 : ツリーの構造で 1 : ベタで\n"
"\n"
" @ファイル名 で、ファイルからオプションスイッチを入力する\n"
" -o の次の引数は、出力ディレクトリを指定して下さい\n"
);
printf(
" 読み飛ばす拡張子の表示 z ( %d 個 + 20 個 あります )\n"
, MAX_ATTR + MAX_ATTR1
);
}
int mallocIdx2()
{
int sw;
long max, min, tmp, size;
max = ( 64L * 1024L ) / (long)sizeof(struct IDX2);
min = 0; tmp = ( max - min ) / 2 + min;
sw = FALSE;
while ( sw == FALSE ) {
size = tmp * sizeof(struct IDX2) ;
if( (idx2 = (struct IDX2 *)malloc(size))==NULL){ max = tmp;
} else { min = tmp; free(idx2);
};
tmp = ( max - min ) / 2 + min;
if ( tmp < 1 ) er_memory( "mallocIdx2 idx2" );
if ( max == min || max - 1 == min ) sw = TRUE;
};
size = tmp * sizeof(struct IDX2) ;
idx2 = (struct IDX2 *)malloc( size );
max_idx2 = tmp;
/*
printf( "%d 個のデータを処理できます(IDX2)\n",tmp);
*/
/*
max = tmp * (long)sizeof(struct IDXS);
*/
max = ( 64L * 1024L ) / (long)sizeof(struct IDXS);
min = 0; tmp = ( max - min ) / 2 + min;
sw = FALSE;
while ( sw == FALSE ) {
size = tmp * sizeof(struct IDXS) ;
if( (idxs = (struct IDXS *)malloc(size))==NULL){ max = tmp;
} else { min = tmp; free(idxs);
};
tmp = ( max - min ) / 2 + min;
if ( tmp < 1 ) er_memory( "mallocIdx2 idxs" );
if ( max == min || max - 1 == min ) sw = TRUE;
};
/* 標準関数の為に残すリアルメモリー容量 */
max = ( 8L * 1024L ) / (long)sizeof(struct IDXS);
tmp -= max;
if ( tmp < 1 ) er_memory( "mallocIdx2 idxs" );
size = tmp * sizeof(struct IDXS) ;
idxs = (struct IDXS *)malloc( size );
max_idxs = tmp;
/*
printf( "%d 個のデータを処理できます(IDXS)\n",tmp);
*/
return( tmp );
}
int mallocIdx()
{
int sw;
long max, min, tmp, size;
max = ( 64L * 1024L ) / (long)sizeof(struct IDX);
min = 0; tmp = ( max - min ) / 2 + min;
sw = FALSE;
while ( sw == FALSE ) {
size = tmp * sizeof(struct IDX) ;
if( (idx = (struct IDX *)malloc(size))==NULL){ max = tmp;
} else { min = tmp; free(idx);
};
tmp = ( max - min ) / 2 + min;
if ( tmp < 1 ) er_memory( "mallocIdx" );
if ( max == min || max - 1 == min ) sw = TRUE;
};
size = tmp * sizeof(struct IDX) ;
idx = (struct IDX *)malloc( size );
max_idx = tmp;
/*
printf( "%d 個のデータを処理できます(IDX)\n",tmp );
*/
return( tmp );
}
static void er_option( char *mes )
{
puts( mes ); exit(1);
}
static void main_loop()
{
int done ;
struct ffblk ffblk;
char inputDir[ MAX_FILENAME_LEN ], *p1, *p2;
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "main_loopです <%s>を調べます\n", InputDir );
};
#endif
CT_fpo = NULL;
if ( ( CT_fpi = fopen( InputDir, "r" ) ) != NULL ) {
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "<%s>ファイル指定\n", InputDir );
};
#endif
fclose( CT_fpi );
/****************************/
/* ファイル名として処理する */
/****************************/
p1 = (char *)last_yen( InputDir );
if ( p1 != InputDir ) p1++; /* p1 : ファイル名 */
/**********************************************/
/* ファイルの存在をチェックしてから処理を行う */
/**********************************************/
doFrom1LOGFile = TRUE;
Check1File( InputDir, p1 );
return;
};
doFrom1LOGFile = FALSE;
/*************************************/
/* InputDir ワイルドカード指定の場合 */
/*************************************/
done = findfirst( InputDir , &ffblk , 0 ); /* ファイルを指定 */
if ( ! done ) {
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "<%s>ワイルドカード指定\n", InputDir );
};
#endif
strcpy( inputDir, InputDir );
p1 = inputDir; if ( *(p1+1) == ':' ) p1 += 2;
p2 = (char *)last_yen( p1 );
*p2 = '\0';
append_yen( inputDir );
while ( ! done ) {
strcpy( InputDir, inputDir ); strcat( InputDir, ffblk.ff_name );
if ( ffblk.ff_attrib != FA_DIREC ) {
/****************************/
/* ファイル名として処理する */
/****************************/
Check1File( InputDir, ffblk.ff_name );
};
done = findnext( &ffblk );
};
return;
};
/***********************************************************/
/* InputDir がディレクトリ指定 or ワイルドカード指定の場合 */
/***********************************************************/
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "<%s>ディレクトリ指定\n", InputDir );
};
#endif
/* InputDir の最後が \ の場合は削除する */
p1 = InputDir; while ( *p1 ) p1++;
p1--;
if ( p1 != InputDir && *p1 == '\\' ) *p1 = '\0';
p1 = InputDir; if ( *(p1+1) == ':' ) p1 += 2;
/* ドライブ指定の場合は *.* を追加する */
if ( *p1 == '\0' ) {
/* inputDir の設定 */
strcpy( inputDir, InputDir );
} else {
append_yen( InputDir );
/* inputDir の設定 */
strcpy( inputDir, InputDir );
};
strcat( InputDir, "*.*" );
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "InputDir=<%s> inputDir=<%s>\n", InputDir, inputDir );
};
#endif
done = findfirst( InputDir , &ffblk , FA_DIREC ); /* Directory を指定 */
while ( ! done ) {
strcpy( InputDir, inputDir ); strcat( InputDir, ffblk.ff_name );
if ( ffblk.ff_attrib == FA_DIREC ) {
if ( NoSubDirSw != TRUE ) {
if ( strcmp( ffblk.ff_name , "." ) != 0
&& strcmp( ffblk.ff_name , ".." ) != 0
) {
/********************************/
/* ディレクトリ名として処理する */
/********************************/
append_yen( InputDir );
ct_findfirst( InputDir, Check1File );
};
};
} else {
/****************************/
/* ファイル名として処理する */
/****************************/
Check1File( InputDir, ffblk.ff_name );
};
done = findnext( &ffblk );
};
return;
}
#define NONE_OPTION 0x00
#define INPUT_OPTION 0x01
#define OUTPUT_OPTION 0x02
#define LOAD_OPTION 0x04
/* 1993.9.15 削除 ******
#define LHA_e_OPTION 0x08
#define LHA_E_OPTION 0x10
************************/
#define TMP_OPTION 0x20
static int setOptions( const char *p )
{
int i, result;
char *p2;
char str[ 128 ];
if ( *p == '-' || *p == '/' ) p++;
result = NONE_OPTION;
while ( *p ) {
switch( *p ) {
/******** 1993.8.7 コメントアウト **************************************
case '?':
useage();
printf( "\n\n"
" また、-z とすると、読み飛ばす拡張子"
"( %d 個)を表示します\n\n"
, MAX_ATTR + MAX_ATTR1
);
exit( 0 );
*************************************************************************/
case '1': treeMode = 1; break;
case '2': treeMode = 0; break;
case 'A': doOnlyCurrentCATLOGFile = TRUE; break;
case 'a': doOnlyCurrentCATLOGFile = FALSE; break;
case 'D': Display = FALSE ; break;
case 'd': Display = TRUE ; break;
/* 1993.9.15 削除 ******
case 'e': result |= LHA_e_OPTION; break;
case 'E': result |= LHA_E_OPTION; break;
*****************/
case 'F': MaxFileSizeSw = TRUE;
p++;
p2 = str; while ( isdigit( *p ) ) { *p2++ = *p++; };
*p2 = '\0';
if ( p2 != str ) MaxSearchFileSize = atol( str ) * 1024L;
p--;
break;
case 'f': MaxFileSizeSw = FALSE;
/* 数字を読み飛ばす */
p++; while ( isdigit( *p ) ) { p++; };
p--;
MaxSearchFileSize= 700L* 1024L;
break;
/*
case 'i': result |= INPUT_OPTION; break;
*/
case 'l': result |= LOAD_OPTION; break;
case 'o': result |= OUTPUT_OPTION; break;
case 'R': NoSubDirSw = TRUE; break;
case 'r': NoSubDirSw = FALSE; break;
case 'T': /* 発言の本体を出力しない */
NoTextSw = TRUE; break;
case 't': /* 発言の本体を出力する */
NoTextSw = FALSE; break;
#if VERIFY == YES
case 'U':
p++; /* skip 'u' */
level_comment = atoi( p ) * 2;
while( isdigit( *p ) ) p++;
p--; /* 1バイト戻しておく */
if ( level_comment > LEVEL_COMMENT ) {
level_comment = LEVEL_COMMENT;
};
break;
case 'u':
p++; /* skip 'U' */
while( isdigit( *p ) ) p++;
p--; /* 1バイト戻しておく */
level_comment = LEVEL_COMMENT;
break;
case 'v': verify = FALSE; break;
case 'V': verify = TRUE; break;
#else
case 'v': break;
case 'V': break;
#endif
case 'w': result |= TMP_OPTION; break;
case 'z': /* 読み飛ばす拡張子を表示する */
spawnlp( P_WAIT, "vmap", "vmap", NULL);
printf( "%d 個のデータを処理できます(IDX2)\n",max_idx2);
printf( "%d 個のデータを処理できます(IDXS)\n",max_idxs);
free( idx2 ); free( idxs ); mallocIdx();
printf( "%d 個のデータを処理できます(IDX)\n",max_idx);
puts( "読み飛ばす拡張は次の通りです" );
for (i=0; i<MAX_ATTR; i++ ) printf( "%s\t", attr[i]);
for (i=0; i<MAX_ATTR1; i++ ) printf( "%s\t", attr1[i]);
puts( "\n次の拡張子も読み飛ばされます" );
puts( "$F0 ~ $F9 , $FA ~ $FK" );
exit( 0 );
default:
sprintf(str,"オプションの指定(%c)が間違っています", *p );
er_option( str );
};
p++;
};
return( result );
}
/* str のファイルを検索して TMP ファイルを作る */
/* 1993.9.15 削除 *******
static void Lha_e_Option( char *str )
{
strcpy( InputDir, str ); append_yen( InputDir );
ct_findfirst( InputDir, Check1File );
fclose( CT_fpo ); CT_fpo = NULL;
OverIdx();
free( idx2 ); free( idxs );
if ( Display == TRUE ) {
if ( HatsugenSu != 0 ) {
printf( "%d 個の発言がありました\n", HatsugenSu );
} else {
puts( "発言が見つかりませんでした" );
};
};
exit( 0 );
}
**************************/
/* DEF FILE 指定 */
static void main_loop_file( const char *file )
{
int sw;
FILE *fpi;
file++;
if ( (fpi=fopen(file,"r")) == NULL ) er_open(file,0,"main_loop_file");
while ( fscanf( fpi, "%s", str ) > 0 ) {
sw = *str;
if ( sw == '@' ) { /* DEF FILE 指定 */
main_loop_file( str );
} else if ( sw == '-' || sw == '/' ) {
sw = setOptions( str );
if ( (sw & TMP_OPTION) != 0 ) {
/* TMPディレクトリの指定 */
if ( fscanf( fpi, "%s", str ) > 0 ) {
strcpy( TmpDir, str ); append_yen( TmpDir );
/********************************************************/
/* comtxt.tmp comtree.tmp comtree0.tmp 会議室.tmpを削除 */
/********************************************************/
deleteComTreeTmpFile();
} else {
er_option("TMPディレクトリを指定して下さい");
};
};
if ( (sw & OUTPUT_OPTION) != 0 ) {
/* 出力ディレクトリの指定 */
if ( fscanf( fpi, "%s", str ) > 0 ) {
strcpy( OutDir, str ); append_yen( OutDir );
/********************************************************/
/* comtxt.tmp comtree.tmp comtree0.tmp 会議室.tmpを削除 */
/********************************************************/
deleteComTreeTmpFile();
} else {
er_option("出力するディレクトリを指定して下さい");
};
};
if ( (sw & LOAD_OPTION) != 0 ) {
if ( fscanf( fpi, "%s", str ) > 0 ) load( atoi( str ) );
};
/* 1993.9.15 削除 *******
if ( (sw & LHA_e_OPTION ) != 0 ) {
if ( fscanf( fpi, "%s", str ) > 0 ) Lha_e_Option( str );
};
if ( (sw & LHA_E_OPTION ) != 0 ) {
SortMainONFile(); exit( 0 );
};
*************************/
} else {
/* 入力ディレクトリの指定 */
strcpy( InputDir, str );
main_loop();
fclose( CT_fpo ); CT_fpo = NULL;
};
};
fclose( fpi );
}
void main( int argc , char *argv[] )
{
int sw;
char *p1 ;
/*
printf( "<%d>個の引数があります\n", argc );
for ( sw=0; sw<argc; sw++ ) printf( "%2d:%s\n", sw, argv[sw]);
printf( "引数は以上でした\n" );
*/
strcpy( FileName, argv[0] ); /* 起動ドライブを知る */
*InputDir = *OutDir = *TmpDir = '\0';
if ( argc == 1 ) { useage(); exit( 1 );
};
/* 内部処理用の領域を確保する */
pool_malloc( );
mallocIdx2();
/********************************* Test *
spawnlp( P_WAIT, "vmap", "vmap", NULL);
CT_fpi = fopen( "main.c", "r" );
if ( CT_fpi == NULL ) { printf( "オープンできません" );
} else {
fgets( str, LINE, CT_fpi );
printf( "%s", str );
};
spawnlp( P_WAIT, "vmap", "vmap", NULL);
fclose( CT_fpi );
spawnlp( P_WAIT, "vmap", "vmap", NULL);
*********************************************************/
/* MS-DOS の環境変数を読み込む */
/*
コマンドラインで指定した方が優先権が上になる。
そこで、最初に環境変数を得る
*/
p1 = getenv( "TMP" );
if ( p1 != NULL ) { strcpy( TmpDir, p1 ); append_yen( TmpDir ); };
p1 = getenv( "CTUSR" );
if ( p1 != NULL ) {
strcpy( str, p1 ); setOptions( str );
};
/****************************************************/
/* 起動時のカレントディレクトリのファイルを削除する */
/* -o 指定が無い場合、必要である */
/****************************************************/
deleteComTreeTmpFile();
*ForumNameLine = '\0';
HatsugenSu=0;
/********************/
/* 入力ディレクトリ */
/********************/
while ( --argc > 0 ) {
++argv;
sw = **argv;
if ( sw == '@' ) { /* DEF FILE 指定 */
main_loop_file( *argv );
} else if ( sw == '-' || sw == '/' ) {
sw = setOptions( *argv );
if ( (sw & TMP_OPTION) != 0 ) {
/* 出力ディレクトリの指定 */
if ( --argc > 0 ) {
++argv;
strcpy( TmpDir, *argv ); append_yen( TmpDir );
/********************************************************/
/* comtxt.tmp comtree.tmp comtree0.tmp 会議室.tmpを削除 */
/********************************************************/
deleteComTreeTmpFile();
} else {
er_option("TMPディレクトリを指定して下さい");
};
};
if ( (sw & OUTPUT_OPTION) != 0 ) {
/* 出力ディレクトリの指定 */
if ( --argc > 0 ) {
++argv;
strcpy( OutDir, *argv ); append_yen( OutDir );
/********************************************************/
/* comtxt.tmp comtree.tmp comtree0.tmp 会議室.tmpを削除 */
/********************************************************/
deleteComTreeTmpFile();
} else {
er_option("出力するディレクトリを指定して下さい");
};
};
if ( (sw & LOAD_OPTION) != 0 ) {
if ( --argc > 0 ) { ++argv; load( atoi( *argv ) ); };
};
/* 1993.9.15 削除 *******
if ( (sw & LHA_e_OPTION ) != 0 ) {
if ( --argc > 0 ) { ++argv; Lha_e_Option( *argv ); };
};
if ( (sw & LHA_E_OPTION ) != 0 ) {
SortMainONFile(); exit( 0 );
};
*************************/
} else {
/* 入力ディレクトリの指定 */
strcpy( InputDir, *argv );
main_loop();
fclose( CT_fpo ); CT_fpo = NULL;
};
};
if ( Display == TRUE ) {
if ( HatsugenSu != 0 ) {
printf( "%d 個の発言がありました\n", HatsugenSu );
} else {
puts( "発言が見つかりませんでした" );
};
};
/* comtree.tmp comtree0.tmp を削除する */
set_tmp_file_name( COMTXT_TMP_FILE, FileName ); remove( FileName );
set_tmp_file_name( COMTREE_TMP_FILE, FileName ); remove( FileName );
set_tmp_file_name( COMTREE0_TMP_FILE, FileName ); remove( FileName );
if ( HatsugenSu > 0 ) {
if ( OverIdxSw == FALSE ) {
OpenComTreeTmpFile( "main" );
SortMainONMemory();
free( idx2 ); free( idxs );
} else {
OverIdx(); /* メモリー上に残っているデータを書き出す */
SortMainONFile( );
};
/* -t option */
if ( NoTextSw == FALSE ) {
fclose( CT_fpiText );
fclose( CT_fpoText );
};
fclose( CT_fpo0 );
fclose( CT_fpo );
};
/**********************/
/* メモリーを解放する */
/**********************/
free( catlog_pool );
/********/
/* 終了 */
/********/
exit( 0 );
}
/* DIVIDE_END */
/* DIVIDE_START=sort.c */
/*
コメントツリー作成プログラム sort.c
作 : 山先(NIFTY-ID:GHH01217)
*/
#include "ct.h"
/*
static int max_sort1_level=0;
*/
static char sort1_line[ LEVEL_COMMENT + 4 ];
static int sort1( int st0 );
static int ahureSw = FALSE;
static int newForumSw = FALSE;
static int newKaigishitsuSw = FALSE;
int sort0LIB( const struct IDX *p1 , const struct IDX *p2 )
{
/* 発言番号→日時の順に並べる */
if(p1->SayNum != p2->SayNum ) return( p1->SayNum - p2->SayNum );
if ( p1->SayDate < p2->SayDate ) return( -1 );
if ( p1->SayDate > p2->SayDate ) return( 1 );
return( 0 );
}
int sort0( const struct IDX *p1 , const struct IDX *p2 )
{
if ( p1->SayDate == p2->SayDate ) return( p1->SayNum - p2->SayNum );
if ( p1->SayDate < p2->SayDate ) return( -1 );
return( 1 );
}
/*********************************************************************/
/* st 以降の発言で moto と同じコメント元番号の発言のポインタ値を返す */
/*********************************************************************/
static int
isComNum( int st, const SayLong sayNum, const SayLong moto )
{
if ( OverIdxSw == TRUE ) {
st++;
for ( ; st < HatsugenSu ; st++ ) {
if ( idx[st].SayNum == (SayLong)0 ) continue;
/* 削除してないデータ */
if ( idx[st].SayNum <= sayNum ) {
/* MAIL , LIB は発言番号の順に並んでいない */
if ( MesNum != MAIL
&& MesNum != LIB
&& MesNum != CLIP
&& MesNum != BILL
) break;
};
if ( idx[st].ahure == 0x00
&& idx[st].ComNum == moto
) return( st );
};
} else {
st++;
for ( ; st < HatsugenSu ; st++ ) {
if ( idx2[st].SayNum == (SayLong)0 ) continue;
/* 削除してないデータ */
if ( idx2[st].SayNum <= sayNum ) {
/* MAIL , LIB は発言番号の順に並んでいない */
if ( MesNum != MAIL
&& MesNum != LIB
&& MesNum != CLIP
&& MesNum != BILL
) break;
};
if ( idx2[st].ahure == 0x00
&& idx2[st].ComNum == moto
) return( st );
};
};
return( -1 );
}
static void sort1_sub2_sub()
{
const char *p;
switch( MesNum ) {
case HP: p = "HP"; break;
case MAIL: p = "MAIL"; break;
case NEW: p = "NEW"; break;
case PATIO: p = "PATIO"; break;
case BILL: p = "BILL"; break;
case CLIP: p = "CLIP"; break;
case LIB: p = "LIB"; break;
default: p = "FORUM"; break;
};
fprintf( CT_fpo, "CHANGE:%s フォーラム名変更\n", p );
}
static void
sort1_sub2( const int st, const char *line0 )
{
int len;
char *p1, *p2, *p3 ;
long seek, mojiSu;
char str1[ 26 ];
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "sort1_sub2 の入口です %ld へ seek します\n"
,idx[st].seek
);
};
#endif
if ( OverIdxSw == TRUE ) {
fseek( CT_fpi, idx[st].seek, SEEK_SET );
/* 2行目:フォーラム名 */
fgets(ForumNameLine,80,CT_fpi);
/* 3行目:会議室名 */
fgets(KNL[0],80,CT_fpi);
/* 4行目:ファイル名 */
fgets( FileName, LINE, CT_fpi);
/* 5行目:発言に関するデータ */
fgets( str, LINE, CT_fpi);
without_crlf( str );
sprintf( str1, " %2d", CommentLevel/2 );
strcat( str, str1 );
/* 6行目:発言の標題 */
fgets( HyoudaiLine, 80, CT_fpi );
/* 特殊な処理 */
if ( MesNum == LIB ) LibNum = atoi( str );
p1 = str; while ( isspace(*p1) ) p1++;
p1 = next_word( p1 ); /* skip 発言番号 */
p1 = next_word( p1 ); /* skip コメント番号 */
seek = atol( p1 );
p1 = next_word( p1 ); /* skip seek 位置 */
mojiSu = atol( p1 );
} else {
/* 2行目:フォーラム名 */
strcpy( ForumNameLine, idxs[idx2[st].ForumNameLine].name );
/* 3行目:会議室名 */
len = idx2[st].KNL;
if ( len < 0 ) { strcpy( KNL[0], ForumNameLine );
} else { strcpy( KNL[0], idxs[len].name );
};
/* 4行目:ファイル名 */
strcpy( FileName, idxs[idx2[st].FileName].name );
/* 5行目:発言に関するデータ */
long_to_date( MesNum, str1, idx2[st].SayDate );
sprintf( str, "%5d %5d %8ld %8ld %5d %5d %10s %2d"
, idx2[st].SayNum
, idx2[st].ComNum
, idx2[st].seek
, idx2[st].blen
, idx2[st].gyou
, idx2[st].glen
, str1
, CommentLevel/2
);
/* 6行目:発言の標題 */
strcpy( HyoudaiLine, idx2[st].HyoudaiLine );
/* 特殊な処理 */
if ( MesNum == LIB ) LibNum = idx2[st].SayNum;
seek = idx2[st].seek;
mojiSu = idx2[st].blen;
};
without_crlf( ForumNameLine );
without_crlf( KNL[0] );
without_crlf( FileName );
without_crlf( HyoudaiLine );
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "FileName = %s\n", FileName );
};
#endif
/* 1993.8.9 追加 フォーラム名変更 */
if ( newForumSw == FALSE ) {
newForumSw = TRUE;
sort1_sub2_sub();
/* 2行目の形式の変更 */
fputs( " 0 0 0 0 0 0 0 -2\n", CT_fpo );
fprintf( CT_fpo ,"%s\n", ForumNameLine );
fprintf( CT_fpo0,"%s\n", ForumNameLine );
if ( Display == TRUE ) printf("%s\n", ForumNameLine );
if ( MesNum == LIB ) newKaigishitsuSw = TRUE;
};
/* 1993.7.24 追加 会議室の変更 */
if ( newKaigishitsuSw == FALSE ) {
newKaigishitsuSw = TRUE;
if ( ( 1 <= MesNum && MesNum <= 20 )
|| MesNum == PATIO
|| MesNum == LIB
) {
/* フォーラムの場合だけ */
if ( MesNum == LIB ) {
fputs( "CHANGE:LIB 会議室名変更\n", CT_fpo );
} else {
fputs( "CHANGE:MES 会議室名変更\n", CT_fpo );
};
/* 2行目の形式の変更 */
fputs( " 0 0 0 0 0 0 0 -1\n", CT_fpo );
fprintf( CT_fpo , "%s\n", KNL[0]);
fprintf( CT_fpo0, "%s\n", KNL[0]);
if ( Display == TRUE ) printf( "%s\n", KNL[0] );
};
};
/* 1行目 */
/*
fprintf(CT_fpo,"%s\n", ForumNameLine );
*/
switch( MesNum ) {
case BILL: sprintf(str1,"BILL"); break;
case CLIP: sprintf(str1,"CLIP"); break;
case NEW: sprintf(str1,"NEW"); break;
case HP: sprintf(str1,"HP:%-8s",ForumName); break;
case MAIL: sprintf(str1,"MAIL:%-8s",ForumName); break;
case PATIO: sprintf(str1,"PATIO:%-8s",ForumName); break;
case LIB: sprintf(str1,"FORUM:%-8s LIB:%d",ForumName,LibNum); break;
default: sprintf(str1,"FORUM:%-8s MES:%d",ForumName,MesNum); break;
};
fprintf( CT_fpo, "%s\n", str1 );
/* 2行目:発言の関するデータ */
fprintf( CT_fpo, "%s\n", str );
/* 3行目:ファイル名 */
fprintf( CT_fpo, "%s\n", FileName );
if ( OverIdxSw == TRUE ) {
len=idx[st].ahure; sayNum=idx[st].SayNum; comNum=idx[st].ComNum;
} else {
len=idx2[st].ahure; sayNum=idx2[st].SayNum; comNum=idx2[st].ComNum;
};
if ( len != 0 ) {
sprintf( str, "%s◆%05u(%05u) %s"
,line0
,sayNum
,comNum
,HyoudaiLine
);
} else {
sprintf( str, "%s%05u %s", line0, sayNum, HyoudaiLine );
};
/**********************/
/* 1行78文字に制限 */
/**********************/
p1 = str; len= 0;
while ( *p1 ) {
if ( iskanji( *p1 ) ) { p1++; len++; };
p1++; len++;
if ( len >=78 ) { *p1 = '\0'; break; };
};
/* 題名(コメントツリー) comtree0.tmp に書き出す */
if ( Display == TRUE ) puts( str );
fprintf( CT_fpo0, "%s\n", str );
/**************************************************/
/* 発言の本体をコピーしないのであれば、ここで終了 */
/**************************************************/
if ( NoTextSw == TRUE ) { /* -t option */
#if VERIFY == YES
if ( verify == TRUE ) {
puts( "sort1_sub2 を終了します" );
};
#endif
return;
};
/**********************/
/* 発言の本体をコピー */
/**********************/
/* 発言本体の出力ファイルの seek 位置を調べるのであればここで行うこと */
switch( MesNum ) {
case BILL: strcpy(str1,"利用料金情報"); break;
case CLIP: strcpy(str1,"クリッピングサービス"); break;
case NEW: strcpy(str1,"今週のお知らせ"); break;
default: break;
};
sprintf( str, "*****log整理(%-21s) %s *****", str1, FileName);
catlog_fprintf( str , CT_fpoText );
/* この発言を CT_fpoText に書き出す */
Copy1Say( seek, mojiSu );
/* 発言の本体を書き出す */
/* ファイルの最後まで書き出す */
/*************************
if ( mojiSu > 0L ) {
seek += mojiSu;
while ( ftell( CT_fpiText ) < seek ) {
fgets( str, LINE, CT_fpiText );
fprintf( CT_fpoText, "%s", str);
};
} else {
while ( fgets( str, LINE, CT_fpiText) != NULL ) {
fprintf( CT_fpoText, "%s", str);
};
};
****************************/
#if VERIFY == YES
if ( verify == TRUE ) {
puts( "sort1_sub2 を終了します" );
};
#endif
}
static void sort1_sub3( const int st1 )
{
int st2, sw;
SayLong sayNum;
/* この発言番号を保存 */
if ( OverIdxSw == TRUE ) { sayNum = idx[st1].SayNum;
} else { sayNum = idx2[st1].SayNum;
};
/****************************/
/* 第1:この発言を表示する */
/****************************/
sort1_line[ CommentLevel ] = '\0'; /* 文字列をこのレベルに初期化 */
/* st1 以後に同じコメント元番号を持つ発言がある? */
if ( OverIdxSw == TRUE ) { sw = isComNum( st1, sayNum, idx[st1].ComNum );
} else { sw = isComNum( st1, sayNum, idx2[st1].ComNum );
};
if ( CommentLevel != 0
|| ahureSw != TRUE
) {
if ( sw > 0 ) { strcat( sort1_line, "┣" ); /* ある */
} else { strcat( sort1_line, "┗" ); /* ない */
};
};
sort1_sub2( st1, sort1_line ); /* この発言をファイルに書き出す */
sort1_line[ CommentLevel ] = '\0'; /* 文字列をこのレベルに初期化 */
/* 第2:st1 をコメント元番号とする発言を探す */
if ( sw > 0 ) { strcat( sort1_line, "┃" ); /* ある */
} else { strcat( sort1_line, " " ); /* ない */
};
CommentLevel += 2; /* レベルを1上げる */
/******************/
/* レベルチェック */
/******************/
#if VERIFY == YES
if ( CommentLevel >= level_comment ) {
#else
if ( CommentLevel >= LEVEL_COMMENT ) {
#endif
/* コメントの階層が深すぎる場合の処理 */
/* この発言をコメント元番号とする発言の ahure を 0x01 にする */
st2 = st1 ;
if ( OverIdxSw == TRUE ) {
while ((st2=isComNum(st2,sayNum,sayNum))>0) idx[st2].ahure=0x01;
} else {
while ((st2=isComNum(st2,sayNum,sayNum))>0) idx2[st2].ahure=0x01;
};
} else {
/* この発言をコメント元番号とする発言を表示する */
st2 = st1 ;
while ((st2=isComNum(st2,sayNum,sayNum)) > 0 ) sort1( st2 );
};
CommentLevel -= 2; /* レベルを1下げる */
/* 処理済の発言とする */
if ( OverIdxSw == TRUE ) {
idx[st1].SayNum = (SayLong)0; idx[st1].ahure = 0x00;
} else {
idx2[st1].SayNum = (SayLong)0; idx2[st1].ahure = 0x00;
};
}
static int sort1( int st0 )
{
int st1, st2, sw;
SayLong moto, sayNum;
#if VERIFY == YES
if ( verify == TRUE ) {
puts( "sort1 の入口です" );
};
#endif
/* コメントツリーの深さを調べる部分 */
/*
if ( max_sort1_level < CommentLevel ) {
max_sort1_level = CommentLevel;
printf( "max_sort1_level = %d\n", max_sort1_level);
};
*/
/* この発言の発言番号 */
if ( OverIdxSw == TRUE ) {
while( idx[st0].SayNum == (SayLong)0 ) {
st0++;
if ( st0 >= HatsugenSu ) return( st0 );
};
moto = idx[st0].ComNum;
sayNum = idx[st0].SayNum;
} else {
while( idx2[st0].SayNum == (SayLong)0 ) {
st0++;
if ( st0 >= HatsugenSu ) return( st0 );
};
moto = idx2[st0].ComNum;
sayNum = idx2[st0].SayNum;
};
for( st2 = st0 ; st2 < HatsugenSu ; st2++ ) {
/* 発言番号が0のものは無視する */
if ( OverIdxSw == TRUE ) { sw = idx[st2].SayNum;
} else { sw = idx2[st2].SayNum;
};
if ( sw == 0 ) continue;
/* より小さな発言番号に当たったら終了 */
if ( st2 != st0 ) {
if ( OverIdxSw == TRUE ) { sw = (idx[st2].SayNum <= sayNum );
} else { sw = (idx2[st2].SayNum <= sayNum);
};
if ( sw ) {
/* 会議室の名前を表示するように */
if ( CommentLevel == 0 ) {
if ( MesNum == NEW ) { newForumSw = FALSE;
} else if ( MesNum != LIB ) { newKaigishitsuSw = FALSE;
};
};
};
break;
};
if ( CommentLevel == 0 ) {
ahureSw = TRUE;
for ( st1=st2 ; st1<HatsugenSu ; st1++ ) {
if ( OverIdxSw == TRUE ) { sw = idx[st1].ahure;
} else { sw = idx2[st1].ahure;
};
if ( sw != 0x00 ) {
/* 1行に溢れた発言の処理 */
sort1_sub3( st1 ); /* この発言を表示する */
};
};
ahureSw = FALSE;
/* 1993.8.21 以下のチェックを追加 */
/* CommentLevel が 0 の場合は 強制的に表示する */
if ( OverIdxSw == TRUE ) { sw = idx[st2].SayNum;
} else { sw = idx2[st2].SayNum;
};
if ( sw != 0 ) {
if ( OverIdxSw == TRUE ) { idx[st2].ComNum = 0;
} else { idx2[st2].ComNum = 0;
};
sort1_sub3( st2 ); /* この発言を表示する */
};
continue;
};
/* コメント元番号が異なれば無視する */
if ( OverIdxSw == TRUE ) { sw = ( idx[st2].ComNum != moto );
} else { sw = ( idx2[st2].ComNum != moto );
};
if ( sw ) continue;
sort1_sub3( st2 ); /* この発言を表示する */
};
/* 文字列をこのレベルに初期化する */
sort1_line[ CommentLevel ] = '\0';
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "sort1(%d)→st1=%d st2=%d を終了します\n", st0, st1, st2 );
};
#endif
return ( st2 );
}
static int Sort1KaigiIsIndex()
{
int i;
SayLong sayNum;
long sayDate;
/* 1993.8.23 追加 今週のお知らせは、とにかく全部ロードする */
if ( MesNum == NEW ) return( FALSE );
sayNum = idx[ HatsugenSu ].SayNum;
sayDate = idx[ HatsugenSu ].SayDate;
for ( i=0; i<HatsugenSu; i++ ) {
if( idx[i].SayNum== sayNum && idx[i].SayDate== sayDate ) return(TRUE);
};
return ( FALSE );
}
/* 1993.8.23 追加 */
/* idx に全部のお知らせが入っている */
/* 発言は番号の小さいものから入っているはずである */
/* そこで、同じ週のお知らせは、日付の一番大きいものに揃えてしまう */
/* そうすると、うまく日時と番号で処理することができるようになる */
void sortNEW( const int st0 )
{
int st1, st2;
int i;
long sayDate;
if ( OverIdxSw == TRUE ) {
for ( st1 = st0 ; st1 < HatsugenSu ; st1++ ) {
for ( st2 = st1 ; st2 < HatsugenSu - 1 ; st2++ ) {
if ( idx[st2].SayNum > idx[st2+1].SayNum ) break;
};
/* st1 ~ st2 の間で 一番大きい発言日時を得る */
sayDate = 0L;
for ( i = st1 ; i <= st2 ; i++ ) {
if ( sayDate < idx[i].SayDate ) sayDate = idx[i].SayDate;
};
/* st1 ~ st2 の発言日時を sayDate にしてしまう */
for ( i = st1 ; i <= st2 ; i++ ) idx[i].SayDate =sayDate;
/* st1 を進める */
st1 = st2;
};
} else {
for ( st1 = st0 ; st1 < HatsugenSu ; st1++ ) {
for ( st2 = st1 ; st2 < HatsugenSu - 1 ; st2++ ) {
if ( idx2[st2].SayNum > idx2[st2+1].SayNum ) break;
};
/* st1 ~ st2 の間で 一番大きい発言日時を得る */
sayDate = 0L;
for ( i = st1 ; i <= st2 ; i++ ) {
if ( sayDate < idx2[i].SayDate ) sayDate = idx2[i].SayDate;
};
/* st1 ~ st2 の発言日時を sayDate にしてしまう */
for ( i = st1 ; i <= st2 ; i++ ) idx2[i].SayDate =sayDate;
/* st1 を進める */
st1 = st2;
};
};
}
/* 1会議室分のデータのツリーを作る */
/* ForumName MesNum を設定してから呼ぶこと */
static void Sort1Kaigi( const char *file )
{
char *p1;
int i, st;
int OverIdxSw0;
long OverIdxSeek;
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "Sort1Kaigi( %s ) です\n", file );
};
#endif
OverIdxSeek = 0L;
Sort1KaigiLoop:
OverIdxSw0 = FALSE;
if ( kbhit() ) {
i = getch(); ungetch( i ); if ( i == ESC ) exit( 1 );
};
/* ファイルの内容をロードする */
HatsugenSu = 0;
if ( initial_check_pool( file ) == TRUE ) {
/* 処理できる数より発言の方が大きくなった場合の処理 */
while ( pool_seek_ichi < OverIdxSeek ) {
CPDS = PSP;
GET_LINE2 break;
};
GET_LINE2 ; /* 先読み 1行目:フォーラム名 会議室番号 */
forever {
CPDS = PSP;
GET_LINE2 break; /* 2行目:フォーラム名の行 */
idx[HatsugenSu].seek = pool_seek_ichi;
present_str_copy( ForumNameLine );
/* 3行目:会議室名の行 */
GET_LINE2 break;
GET_LINE2 break; /* 4行目:ファイル名 */
GET_LINE2 break; /* 5行目:発言のデータ */
/*******************************************************
発言番号、
コメント元番号、
ファイル中での位置(seek位置)、
発言のバイト数(標題の行の文字数も含みます)
発言の開始行
発言の終了行
発言の日時
********************************************************/
p1 = PSP; while ( isspace(*p1) ) p1++;
idx[HatsugenSu].SayNum = atol( p1 ) & 0xffff;
p1 = next_word( p1 ); /* skip 発言番号 */
idx[HatsugenSu].ComNum = atol( p1 ) & 0xffff;
p1 = next_word( p1 ); /* skip コメント元番号 */
p1 = next_word( p1 ); /* skip (seek位置) */
p1 = next_word( p1 ); /* skip 発言のバイト数 */
p1 = next_word( p1 ); /* skip 発言の開始行 */
p1 = next_word( p1 ); /* skip 発言の終了行 */
idx[HatsugenSu].SayDate = date_to_long( MES, p1 );
#if VERIFY == YES
if ( verify == TRUE ) {
long_to_date( MesNum, str, idx[HatsugenSu].SayDate );
printf( "値 :Say:%05d Com:%05d Seek:%8ld Date:%s\n"
,idx[HatsugenSu].SayNum
,idx[HatsugenSu].ComNum
,idx[HatsugenSu].seek
,str
);
};
#endif
/* 6行目:発言の題名 */
GET_LINE2 break;
if ( Sort1KaigiIsIndex() == FALSE ) {
idx[HatsugenSu].ahure = 0x00;
HatsugenSu++;
if ( max_idx <= HatsugenSu ) {
puts( "発言の数が多くて処理できません" );
OverIdxSeek = pool_seek_ichi;
OverIdxSw0 = TRUE;
break;
/*
exit( 1 );
*/
};
};
GET_LINE2 break; /* → フォーラム名 会議室番号 */
};
end_check_pool();
};
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "<%d>個の発言がありました\n", HatsugenSu );
};
#endif
if ( HatsugenSu == 0 ) return;
#if VERIFY == YES
if ( verify == TRUE ) {
puts( "まず発言日時でソートし、次に発言番号の順に並べる" );
};
#endif
if ( HatsugenSu > 1 ) {
switch( MesNum ) {
case LIB:
qsort( (char *)idx, HatsugenSu, sizeof(struct IDX), sort0LIB );
break;
case NEW:
sortNEW( 0 );
/* 発言日時 発言番号の順でソートする */
qsort( (char *)idx, HatsugenSu, sizeof(struct IDX), sort0 );
/* 同じ発言日時 発言番号のものは 削除する */
for ( st = 0 ; st < HatsugenSu - 1 ; st++ ) {
if ( idx[st].SayNum == idx[st+1].SayNum
&& idx[st].SayDate == idx[st+1].SayDate
) idx[st].SayNum = 0;
};
break;
default:
qsort( (char *)idx, HatsugenSu, sizeof(struct IDX), sort0 );
break;
};
};
/**********************/
/* ファイルのオープン */
/**********************/
if ( (CT_fpi=fopen( file, "r") ) == NULL ) er_open(file, 0, "Sort1Kaigi");
#if VERIFY == YES
if ( verify == TRUE ) {
if ( MesNum <= 20 ) {
printf( "FORUM:%s\n%5d:%s\n"
,ForumNameLine,MesNum,KNL[ MesNum ]
);
} else {
printf( " I D :%s %5d\n",ForumNameLine,MesNum);
};
};
#endif
if ( treeMode == 1
/*
|| MesNum == MAIL
|| MesNum == LIB
|| MesNum == HP
*/
) {
/* 全てのコメント元番号を 0 にする */
for ( i=0; i<HatsugenSu; i++ ) idx[i].ComNum = 0;
} else {
/* 最初の発言番号よりも小さなコメント元番号は 0 にする */
sayNum = idx[0].SayNum; idx[0].ComNum = 0;
for ( i=1; i<HatsugenSu; i++ ) {
/* 1993.8.21 以下の判定を追加 */
if ( idx[i-1].SayNum > idx[i].SayNum ) {
/* この発言番号が前の発言番号よりも小さい場合 */
/* sayNum を変更し idx[i].ComNum を0にする */
sayNum = idx[i].SayNum;
idx[i].ComNum = 0;
};
if ( idx[i].ComNum < sayNum ) idx[i].ComNum = 0;
};
};
CommentLevel = 0; *sort1_line = '\0'; i = 0;
while ( ( i= sort1(i) ) < HatsugenSu ) ;
#if VERIFY == YES
/* 処理されなかった発言 */
puts( "処理されなかった発言" );
st = 0;
for ( i=0; i<HatsugenSu; i++ ) {
if ( idx[i].SayNum != 0 ) {
st++;
sort1( i );
};
};
if ( st == 0 ) { puts( "ありませんでした" );
} else { printf( "%d 個ありました\n", st );
};
#endif /* VERIFY */
fclose(CT_fpi);
/* 処理できる数より大きい場合 */
if ( OverIdxSw0 == TRUE ) goto Sort1KaigiLoop;
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "Sort1Kaigi( %s ) を終了します\n", file );
};
#endif
}
static void
SortMainONFileSub( const char *typ, const int max, const int mes )
{
int i, done ;
struct ffblk ffblk;
char *p, FileName[ MAX_FILENAME_LEN ];
MesNum = mes;
strcpy( FileName, TmpDir);
strcat( FileName, "*.$");
strcat( FileName, typ);
strcat( FileName, "?");
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "SortMainONFileSub <%s>を調べます\n", FileName);
};
#endif
if ( ( done = findfirst( FileName, &ffblk, 0) ) != 0 ) return;
while ( ! done ) {
if ( ffblk.ff_attrib != FA_DIREC ) {
/* ファイル名 */
strcpy( ForumName, ffblk.ff_name);
p = (char *)last_comma( ForumName);
if ( p != ForumName ) *p = '\0'; /* ファイル名だけにする */
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "SortMainONFileSub <%s>が見つかりました\n", ForumName);
};
#endif
/*
if ( MesNum == LIB ) { newForumSw = TRUE;
} else { newForumSw = FALSE;
};
*/
newForumSw = FALSE;
for ( i=0; i<=max; i++ ) {
if ( i < 10 ) {
sprintf(FileName,"%s%s.$%s%d",TmpDir,ForumName,typ,i);
} else {
sprintf(FileName,"%s%s.$%s%c",TmpDir,ForumName,typ,'A'+i-10);
};
if ( access( FileName, 0 ) == 0 ) {
/* そのファイルについてツリーを作る */
if ( strcmp( typ, "F") == 0 ) MesNum = i;
newKaigishitsuSw = FALSE;
Sort1Kaigi( FileName );
/* 削除する */
remove( FileName );
};
};
/* typ が F であった場合 DL を表示する */
if ( strcmp( typ, "F" ) == 0 ) {
sprintf(FileName,"%s%s.$%s%d",TmpDir,ForumName,"L",0);
if ( access( FileName, 0 ) == 0 ) {
/* そのファイルについてツリーを作る */
/*
newForumSw = TRUE;
*/
newKaigishitsuSw = FALSE;
MesNum = LIB;
Sort1Kaigi( FileName );
/* 削除する */
remove( FileName );
};
};
};
done = findnext( &ffblk );
};
}
void SortMainONFile( )
{
/* ヒープ領域を解放する */
free( idx2 ); free( idxs );
OverIdxSw = TRUE;
/******************************/
/* ソートの為の領域を確保する */
/******************************/
if ( mallocIdx() <= 0 ) er_memory( "mallocIdx" );
OpenComTreeTmpFile( "SortMainONFile" );
/* 1つにまとめた MAIL ファイルである */
/*
SortMainONFileSub( "A", 0, ALL_MAIL );
*/
SortMainONFileSub( "B", 0, BILL ); /* 利用料金情報である */
SortMainONFileSub( "C", 0, CLIP ); /* クリッピングサービスである */
SortMainONFileSub( "F", 20, MES ); /* フォーラムの会議室である */
SortMainONFileSub( "L", 20, LIB ); /* DLである */
SortMainONFileSub( "H", 0, HP ); /* Home Party である */
/* ID収集ファイルである */
/*
SortMainONFileSub( "I", 0, COLLECT_ID );
*/
SortMainONFileSub( "M", 0, MAIL ); /* 電子メールである */
SortMainONFileSub( "N", 0, NEW ); /* 「今週のお知らせ」 */
SortMainONFileSub( "P", 0, PATIO); /* PATIO である */
free( idx );
}
/* s0 ~ s1 が 同じフォーラムの同じ会議室 */
static void SortMainONMemorySub1( int st0 )
{
int st;
/* 同じ発言日時 発言番号のものは 削除する */
for ( st = st0 ; st < HatsugenSu - 1 ; st++ ) {
if ( idx2[st].SayNum == idx2[st+1].SayNum
&& idx2[st].SayDate == idx2[st+1].SayDate
) idx2[st].SayNum = 0;
};
if ( treeMode == 1
/*
|| MesNum == MAIL
|| MesNum == LIB
|| MesNum == HP
*/
) {
/* 全てのコメント元番号を 0 にする */
for ( st=st0; st<HatsugenSu; st++ ) idx2[st].ComNum = 0;
} else {
/* 最初の発言番号よりも小さなコメント元番号は 0 にする */
sayNum = idx2[st0].SayNum; idx2[st0].ComNum = 0;
for ( st=st0+1; st<HatsugenSu; st++ ) {
/* 1993.8.21 以下の判定を追加 */
if ( idx2[st-1].SayNum > idx2[st].SayNum ) {
/* この発言番号が前の発言番号よりも小さい場合 */
/* sayNum を変更し idx2[st].ComNum を0にする */
sayNum = idx2[st].SayNum;
idx2[st].ComNum = 0;
};
if ( idx2[st].ComNum < sayNum ) idx2[st].ComNum = 0;
};
};
CommentLevel = 0; *sort1_line = '\0'; st = st0;
while ( ( st= sort1(st) ) < HatsugenSu ) ;
}
void SortMainONMemory()
{
int f0, m0;
int f1, m1;
SortIdx2();
/* 同じ発言日時 発言番号のものは 削除する */
for ( f0 = 0 ; f0 < idx2P - 1 ; f0++ ) {
if ( idx2[f0].SayNum == idx2[f0+1].SayNum
&& idx2[f0].SayDate == idx2[f0+1].SayDate
) idx2[f0].SayNum = 0;
};
f0 = 0;
while ( f0 < idx2P ) {
/* 同じフォーラムについて処理する */
sayNum = idx2[f0].ForumName;
if ( ( MesNum = idx2[f0].MesNum ) > 20 ) {
for ( f1=f0+1; f1<idx2P; f1++ ) {
if ( sayNum != idx2[f1].ForumName ) break;
if ( MesNum != idx2[f1].MesNum ) break;
};
} else {
for ( f1=f0+1; f1<idx2P; f1++ ) {
if ( sayNum != idx2[f1].ForumName ) break;
};
};
/* f0 ~ f1 が同一フォーラム */
/*
printf( "%2d ~ %2d が同一フォーラムです\n", f0, f1-1 );
*/
strcpy( ForumName, idxs[idx2[f0].ForumName].name );
newForumSw = FALSE;
m0 = f0;
while ( m0 < f1 ) {
/* 同じ会議室番号について処理する */
sayNum = idx2[m0].MesNum;
for ( m1=m0+1; m1<f1; m1++ ) {
if ( sayNum != idx2[m1].MesNum ) break;
};
/* m0 ~ m1 が同一会議室 */
/*
printf( "\t%2d ~ %2d が同一会議室です\n", m0, m1-1 );
*/
/* 広域変数の設定 */
HatsugenSu = m1; MesNum = idx2[m0].MesNum;
newKaigishitsuSw = FALSE;
if ( MesNum == LIB && newForumSw == FALSE ) newKaigishitsuSw =TRUE;
SortMainONMemorySub1( m0 );
m0 = m1; /* m0 を進める */
};
f0 = f1; /* f0 を進める */
};
}
/* DIVIDE_END */
/* DIVIDE_START=sub.c */
/*
GUI-CATLOG補助プログラム sub.c
1993.5.10
このファイルでは、様々な補助関数を定義している。
*/
#include "ct.h"
static int isCLIPLine( void );
static int isBILLLine( void );
static int isBILL_Sw = FALSE;
int isMesEnd( )
{
char *p1, *p2;
if ( PSL < 5 ) return( NO );
/* NIFTY の新形式 1993.7.4 追加 */
/* 下の命令は <Nakatani> さんより教えていただいた */
if ( *(long *)PSP == 0x0a0d0820LU ) return( YES );
/*
if ( *PSP == 0x20
&& *(PSP+1) == 0x08
&& *(PSP+2) == 0x0d
&& *(PSP+3) == 0x0a
) return( YES );
*/
if ( MesNum == NEW
|| MesNum == CLIP
) {
/* 1993.8.22 「今週のお知らせ」に対応。以下の2つの文字列を追加した */
/* 「今週のお知らせ」の後は、以下の文字列だけを受け付ける */
if(matchstr("続き (改行で次文書 E:終了)",PSP)==TRUE) return( YES );
if(matchstr("表示終了",PSP)==TRUE) return( YES );
if ( MesNum == CLIP ) {
if ( isCLIPLine() == YES ) return( YES );
};
return( NO );
};
if ( MesNum == BILL ) {
if(matchstr("日毎情報 (改行で表示 E:終了)",PSP)==TRUE) return( YES );
if ( isCATLOGFileSw == TRUE ) {
if ( NSP == NULL ) return( YES );
};
if ( isBILLLine() == NO ) return( NO );
if ( isBILL_Sw == FALSE ) {
isBILL_Sw = TRUE;
set_hatsugen_date( BILL, PSP, str ); /* 年月のみ設定 */
sayNum=atoi( str ); /* 年月 */
sayDate = date_to_long( BILL, str );
p1 = HyoudaiLine; p2 = PSP;
while ( *p1 ) p1++;
/* 6文字コピー */
*p1++ = *p2++; *p1++ = *p2++; *p1++ = *p2++;
*p1++ = *p2++; *p1++ = *p2++; *p1++ = *p2++;
*p1 = '\0';
};
sayDate += atol( PSP + 6 );
return( NO );
};
if ( MesNum == LIB ) {
/* isLIBMes */
if ( isLIBLine() == NO ) {
if ( matchstr( "番号 (改行で次頁)", PSP ) == TRUE
&& NSL == 4
&& matchstr( ">", NSP ) == TRUE
) return( NO );
return( YES );
};
sayDate += atol( PSP + 32 );
return( NO );
};
if ( isMesInputLine( PSP ) == YES ) return( YES );
/* - FTOWNS1 : フォーラム名 */
if ( isMesForumNameLine_sub( PSP , PSL ) == YES ) return( YES );
/* 発言の表題の行 */
if ( isMesHyoudaiLine( PSP ) == YES ) return( YES );
if ( matchstr( "電子会議 (1:発言" , PSP ) == TRUE ) return( YES );
if ( matchstr( "電子会議 (1:コメ" , PSP ) == TRUE ) return( YES );
if ( matchstr( "電子会議 (改行の" , PSP ) == TRUE ) return( YES );
if ( matchstr( ">◆次頁はありません◆",PSP ) == TRUE ) return( YES );
if ( matchstr( "◆次頁はありません◆",PSP ) == TRUE ) return( YES );
if ( matchstr("*****log整理",PSP ) == TRUE ) return( YES );
/* int isMailEnd() */
if ( isMAILFirstLine() == YES ) return( YES );
if ( matchstr( "受信後 (1:削除" ,PSP ) == TRUE ) return( YES );
/* int isPATIOEnd() */
if ( isPATIOFirstLine() == YES ) return( YES );
if ( strncmp( PSP , "PATIO(" , 6 ) == 0
&& ( *( PSP + 6 ) == 'R'
|| *( PSP + 6 ) == 'N'
|| *( PSP + 6 ) == 'C'
)
&& strncmp( PSP + 7 , ")>" , 2 ) == 0
) {
/************************************************************/
/* PATIO(?)> : end 条件に入れることは問題があるかもしれない */
/************************************************************/
if ( PSL == 11 ) return( YES );
p1 = PSP + 9;
if ( PSL > 15 /* 15 : "PATIO(R)>GO " + 3 +3:CrLf+1 */
&& ( strncmp( p1 , "GO " , 3 ) == 0
|| strncmp( p1 , "go " , 3 ) == 0
)
) return( YES );
if ( PSL == 41 /*123456789 123456789 123456789 */
&& strncmp( p1 , "-これ以上の発言はありません-" , 30 ) == 0
) return( YES );
};
/* int isHPEnd() */
if ( isHPFirstLine() == YES ) return( YES );
if ( matchstr( "HP>", PSP ) == TRUE ) {
/******************************************************/
/* HP> : end 条件に入れることは問題があるかもしれない */
/******************************************************/
if ( PSL == 5 ) /* 3 + 2 : +2 は cr lf の為 */ return( YES );
p1 = PSP + 3;
if ( PSL >= 8 /* 3 + 3 + 2 : "HP>MOV" cr lf で8バイト */
&& ( strncmp( p1 , "GO " , 3 ) == 0
|| strncmp( p1 , "go " , 3 ) == 0
|| strncmp( p1 , "MOV" , 3 ) == 0
)
) return ( YES );
};
/* 1993.8.9 以下の2つの文字列を追加した */
if ( matchstr("ID (改行のみ:自分のHP)",PSP) == TRUE ) return( YES );
if ( matchstr("ID (改行のみ:自分のパティオ)",PSP)==TRUE) return( YES );
return( NO );
}
void set_ForumNameLine( int mes )
{
if ( *ForumName == '\0' ) strcpy( ForumName, "UNKNOWN" );
switch( mes ) {
case PATIO:
sprintf(ForumNameLine,"PATIO:%s のPATIOです", ForumName );
break;
case HP:
sprintf(ForumNameLine,"HP:%s のHPです", ForumName );
break;
case MAIL:
sprintf(ForumNameLine,"MAIL:%s からのMAILです",ForumName );
break;
case LIB:
sprintf(ForumNameLine,"LIB:%s のDLです",ForumName );
break;
case NEW:
strcpy(ForumNameLine, "NEW: 今週のお知らせ " );
break;
case CLIP:
strcpy(ForumNameLine, "CLIP: クリッピングサービス " );
break;
case BILL:
strcpy(ForumNameLine, "BILL: 利用料金情報 " );
break;
default:
sprintf(ForumNameLine,
"FORUM or ID:%s 会議室番号=<%d>の発言です",
ForumName,
mes
);
break;
};
}
void present_str_copy( char *str )
{
strncpy(str, PSP, PSL); str[ PSL - 2 ]='\0';
};
int matchstr( const char *form, const char *trg )
{
while ( *form ) {
switch( *form ) {
case '%': if ( ! isdigit( *trg ) ) return( FALSE );
break;
case '$': if ( ! isalpha( *trg ) ) return( FALSE );
case '?': break;
default: if ( *form != *trg ) return( FALSE );
};
form++; trg++;
};
return( TRUE );
}
int isIDname( char *str )
{
if ( matchstr( "$$$%%%%%" , str ) == TRUE ) return( YES );
return( NO );
}
static int isMesHyoudaiLine( char *str )
{
/* 123456789 123456789 123456789 1234567 */
if ( matchstr( "%%%/%%% $$$%%%%% ???????????????? ",str) == TRUE ) {
return( YES );
};
/* SYSOP 削除 */
if ( matchstr( "%%%/%%% ******** ???????????????? ",str) == TRUE ) {
return( YES );
};
/* 0123456789 123456789 123456789 123456789 123456789 */
if ( matchstr( "%%%%%/%%%%% $$$%%%%% ???????????????? ",str) == TRUE ) {
return( YES );
};
/* SYSOP 削除 */
if ( matchstr( "%%%%%/%%%%% ******** ???????????????? ",str) == TRUE ) {
return( YES );
};
return( NO );
}
/***********************************************************************/
/* 会議室番号の行? */
/* 1 2 3 4 */
/* 123456789 123456789 123456789 1234567 */
/* ( 1) 89/04/13 20:39 006へのコメント */
/* ( 1) 92/09/18 14:05 コメント数:1 */
/* ( 2) 92/05/04 03:20 */
/***********************************************************************/
static int isMesSecondLine( char *str )
{
if ( matchstr( "(?%) %%/%%/%% %%:%%" , str ) == TRUE ) return( YES );
if ( matchstr( " %%/%%/%% %%:%%" , str ) == TRUE ) return( YES );
return( NO );
}
/***********************************************************************/
/* */
/* フォーラム名の行? */
/* */
/* - FTOWNS1 MES(18):通信ソフトについて(3) 92/04/25 - */
/* */
/***********************************************************************/
static int isMesForumNameLine_sub( char *str , int len )
{
char *p1;
if ( len == 0 ) return( NO );
/********************************************/
/* F で始まらないフォーラムへも対応 92.7.17 */
/********************************************/
if ( strncmp( str,"- ",2) !=0 ) return( NO );
p1 = str + 2;
/* フォーラム名 : 英数字 ? */
while ( isalnum( *p1 ) ) p1++;
/* 2つの空白 */
if ( *p1++ != ' ' ) return( NO );
if ( *p1++ != ' ' ) return( NO );
/* - FTOWNS1 MES( 3): */
if ( strncmp( p1 , "MES(" , 4 ) != 0 ) return( NO );
p1 += 4;
if ( (! isdigit( *p1 ) ) && *p1 != ' ' ) return( NO );
p1++;
if ( ! isdigit( *p1 ) ) return( NO );
p1++;
if ( *p1++ != ')' ) return( NO );
if ( *p1++ != ':' ) return( NO );
return( YES );
}
static int isMAILFirstLine()
{
if ( PSL < 43 ) return( NO );
if ( PSP[3] != ' ' && PSP[3] != '#' ) return( NO );
if (matchstr("?% ????????????????? $$$%%%%% %%/%% %%:%%",PSP)!=TRUE
&& matchstr("?% ????????????????? $$$%%%%% %%/%%/%% %%:%%",PSP)
!=TRUE
) {
return( NO );
};
if ( matchstr( " 題名:", NSP ) == TRUE ) return( YES );
return( NO );
}
static int isPATIOFirstLine()
{
if ( isMesHyoudaiLine( PSP ) == YES
&& *( PSP + 5 ) == '/' /* 新形式の発言形式だけに */
&& isMesSecondLine( NSP ) == YES
) return( YES );
return( NO );
}
static int isHPFirstLine()
{
if ( PSL < 38 ) return( NO );
if ( matchstr( "%%% [%%/%%/%% %%:%%] $$$%%%%% " , PSP ) != TRUE ) {
return( NO );
};
return( YES );
}
static int isMesInputLine( char *ptr )
{
if(matchstr("?:お知らせ ?:掲示板 ?:電子会議",ptr)==TRUE){
return( YES );
};
return( NO );
}
int isMAILMes( )
{
if ( isMAILFirstLine() != YES ) return( FALSE );
/*
>0123456789 123456789 123456789 123456789 123456789 123456789
> 1 #山先 GHH01217 08/04 07:34
*/
strncpy( ForumName, PSP+22, 8 ); ForumName[ 8 ] = '\0';
set_ForumNameLine( MAIL );
MesNum = MAIL; comNum = 0;
StartMesSw = FALSE; /* 以下は MES ではない */
sayNum=atoi( PSP );
set_hatsugen_date( MAIL, PSP, str );
sayDate = date_to_long( MAIL, str );
/* 題名のセット */
set_hyoudaiName( MAIL );
return( TRUE );
}
/****************************************************************************
> 1 2 3 4 5
> 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
>番号 提供日付 題名
> 1 1/08 15:09 時: ◎CDROMで特許出願公開
> 2 1/08 12:01 時: ◎松下、米ベンチャー企業に出資
*****************************************************************************/
static int isBILLLine()
{
if ( PSL < 24 ) return( NO );
if ( matchstr( "%%/%% ?????% ?????????% ????????????????% ??????????????????% ????????????????%", PSP ) == FALSE ) return( NO );
return( YES );
}
int isBILLMes()
{
char *p1, *p2;
if ( matchstr( "利用料金情報 BILL",PSP) == TRUE ) {
MesNum = BILL; set_ForumNameLine( BILL );
strcpy( ForumName, "BILL" );
return( FALSE );
};
if ( MesNum != BILL ) return( FALSE );
if ( matchstr( " あなたの御利用状況は次のとおりです", PSP ) == TRUE ) {
comNum = 0;
isBILL_Sw = FALSE;
/* 題名のセット */
strcpy( HyoudaiLine, ForumNameLine );
/* ここから表示するので TRUE で return する */
return( TRUE );
};
return( FALSE );
}
/****************************************************************************
> 1 2 3 4 5
> 123456789 123456789 123456789 123456789 123456789 123456789 123456789 1234
>番号 提供日付 題名
> 1 1/08 15:09 時: ◎CDROMで特許出願公開
> 2 1/08 12:01 時: ◎松下、米ベンチャー企業に出資
*****************************************************************************/
static int isCLIPLine()
{
if ( PSL < 24 ) return( NO );
if ( matchstr( "??% ?%/%% %%:%% ??: ?", PSP ) == FALSE ) return( NO );
return( YES );
}
int isCLIPMes()
{
if ( matchstr( "クリッピングサービス CLIP",PSP) == TRUE ) {
MesNum = CLIP;
strcpy( ForumName, "CLIP" );
set_ForumNameLine( CLIP );
return( FALSE );
};
if ( MesNum != CLIP ) return( FALSE );
/* 123456789 123456789 123456789 123456 */
if ( matchstr( "番号 提供日付 題名", PSP ) == TRUE ) {
forever {
GET_LINE2 break; /* 先読み */
if ( strncmp( PSP, ">", 2)==0) break; /* 行頭の「>」で終了 */
if ( atoi( PSP ) == 0 ) break; /* 終了 */
};
return( FALSE );
};
if ( isCLIPLine() == NO ) return( FALSE );
sayNum=atoi( PSP );
MesNum = CLIP; comNum = 0;
set_hatsugen_date( CLIP, PSP, str );
sayDate = date_to_long( CLIP, str );
/* 題名のセット */
set_hyoudaiName( CLIP );
return( TRUE );
}
int isNEWFirstLine()
{
if ( PSL < 38 ) return( NO );
/* 123456789 */
if ( matchstr( " ?% %%/%%/%% ?" , PSP ) != TRUE ) {
return( NO );
};
return( YES );
}
static char NEWDate[ 10 ];
int isNEWMes( )
{
if ( matchstr( "今週のお知らせ NEW", PSP ) == TRUE ) {
*NEWDate = '\0';
strcpy( ForumName, "NEW" );
MesNum = NEW;
StartMesSw = FALSE; /* 以下は MES ではない */
return( FALSE );
};
if ( MesNum != NEW ) return( FALSE );
if ( isNEWFirstLine() != YES ) return( FALSE );
sayNum=atoi( PSP );
MesNum = NEW; comNum = 0;
set_hatsugen_date( NEW, PSP, str );
sayDate = date_to_long( NEW, str );
/* 題名のセット */
set_hyoudaiName( NEW );
/* 最初の日付を入れておく */
if ( *NEWDate == '\0' ) { /* 8文字転送 */
strncpy( NEWDate, PSP + 6, 8 ); NEWDate[ 8 ] = '\0';
};
set_ForumNameLine( NEW ); strcat( ForumNameLine, NEWDate );
return( TRUE );
}
int isHPMes( )
{
if ( matchstr( "ID (改行のみ:自分のHP)", PSP ) == TRUE ) {
GET_LINE2 return( FALSE );
if ( strncmp( ":", PSP, 2 ) != 0 ) return( FALSE );
strncpy( ForumName, PSP+2, 8 ); ForumName[ 8 ] = '\0';
touppers( ForumName );
set_ForumNameLine( HP );
MesNum = HP;
StartMesSw = FALSE; /* 以下は MES ではない */
return( FALSE );
};
if ( MesNum != HP ) return( FALSE );
if ( isHPFirstLine() != YES ) return( FALSE );
sayNum=atoi( PSP );
MesNum = HP; comNum = 0;
set_hatsugen_date( HP, PSP, str );
sayDate = date_to_long( HP, str );
/* 題名のセット */
set_hyoudaiName( HP );
return( TRUE );
}
int isPATIOMes( )
{
int line;
/* PATIO の入口から開設者の ID を取得する */
if ( matchstr( "ID (改行のみ:自分のパティオ)", PSP ) == TRUE ) {
GET_LINE2 return( FALSE );
if ( strncmp( ":", PSP, 2 ) != 0 ) return( FALSE );
strncpy( ForumName, PSP+2, 8 ); ForumName[ 8 ] = '\0';
touppers( ForumName );
set_ForumNameLine( PATIO );
StartMesSw = FALSE; /* 以下は PATIO の発言であるという印 */
MesNum = PATIO;
return( FALSE );
};
if ( MesNum != PATIO ) return( FALSE );
/* フォーラムの会議室の発言と区別を付けるため */
/* 以下の処理は StartMesSw が FALSE でないと処理しない */
if ( StartMesSw == TRUE ) return( FALSE );
/* 123456789 123456789 123456789 123456 */
if ( matchstr( "番号 発言 (未読) 最新 会議室名", PSP ) == TRUE ) {
/* 会議室の一覧を KNL に入れる */
/* 初期化 */
for ( line=1; line<21; line++ ) *KNL[ line ] = '\0';
forever {
GET_LINE2 break; /* 先読み */
if ( strncmp( PSP, ">", 2)==0) break; /* 行頭の「>」で終了 */
line = atoi( PSP );
if ( line == 0 ) break; /* 終了 */
if ( line > 20 ) break; /* 終了 */
strncpy( KNL[ line ], PSP, PSL);
KNL[ line ][ PSL-2 ] = '\0';
};
return( FALSE );
};
if ( isPATIOFirstLine() != YES ) return( FALSE );
sayNum=atoi( PSP );
MesNum = PATIO; comNum = 0;
if ( NSL > 23 ) {
comNum = atoi( NSP + 23 );
};
set_hatsugen_date( PATIO, NSP, str );
sayDate = date_to_long( PATIO, str );
/* 題名のセット */
set_hyoudaiName( PATIO );
return( TRUE );
}
/**********************************************/
/* フォーラムの入口からフォーラム名を取り出す */
/**********************************************/
static int get_forum_name_last_str( const char *ptr )
{
int sw;
const char *p1;
char *p2;
p1 = ptr; sw = FALSE;
while ( *p1 ) {
if( *(long *)p1 == 0x20202020LU ) {
sw = TRUE; break;
};
p1++;
};
if ( sw == FALSE ) return( FALSE );
p1 += 4; p2 = ForumName;
while ( isalnum( *p1 ) ) *p2++ = *p1++;
*p2 = '\0';
return( TRUE );
}
void SaveTmpKaigishitsuNameLine( int typ )
{
int line;
char strS[ 40 ];
FILE *fp;
/* 会議室の一覧を KNL に入れる */
/* 初期化 */
for ( line=1; line<21; line++ ) *KNL[ line ] = '\0';
forever {
GET_LINE2 break; /* 先読み */
if ( strncmp( PSP, ">", 2)==0) break; /* 行頭の「>」で終了 */
line = atoi( PSP );
if ( line == 0 ) break; /* 終了 */
if ( line > 20 ) break; /* 終了 */
strncpy( KNL[ line ], PSP, PSL);
KNL[ line ][ PSL-2 ] = '\0';
if ( strncmp( NSP, ">", 2)==0) break; /* 行頭の「>」で終了 */
};
/* すでに登録済なら終了 */
if ( typ == MES ) { sprintf( strS, "FORUM:%s\n" , ForumName );
set_tmp_file_name( KAIGISHITSU_TMP_FILE, FileName );
} else if ( typ == LIB ) { sprintf( strS, "LIB:%s\n" , ForumName );
set_tmp_file_name( DL_TMP_FILE, FileName );
};
if ( ( fp = fopen( FileName, "r") ) != NULL ) {
while( fgets(str, LINE, fp) != NULL ) {
if ( strcmp( str, strS ) == 0 ) {
fclose( fp ); return;
};
};
fclose( fp );
};
/* データをセーブする */
if ( ( fp = fopen( FileName,"a") ) == NULL ) {
er_open(FileName, 1, "SaveTmpKaigishitsuNameLine");
};
if ( typ == MES ) { fprintf( fp, "FORUM:%s\n" , ForumName );
set_tmp_file_name( KAIGISHITSU_TMP_FILE, FileName );
} else if ( typ == LIB ) { fprintf( fp, "LIB:%s\n" , ForumName );
set_tmp_file_name( DL_TMP_FILE, FileName );
};
fprintf( fp, "%s\n", ForumNameLine );
if ( typ == MES ) {
fprintf( fp, "番号 発言 (未読) 最新 会議室名\n" );
} else if ( typ == LIB ) {
fprintf( fp, "番号 総数 登録済 最新 ライブラリ名\n" );
};
for( line=1; line<=20; line++ ) {
if ( *KNL[ line ] != '\0' ) {
fprintf( fp , "%s\n" , KNL[ line ] );
};
};
fprintf( fp, "\n" );
fclose( fp );
}
/*
00102/00107 GBH02001 座敷わらし アフターダークはTOWNSで動かない?
(17) 93/08/21 15:40 コメント数:2
00103/00107 ACT12640 マシーン RE:アフターダークはTOWNSで動かない?
(17) 93/08/21 18:57 00102へのコメント コメント数:2
*/
int isFORUMMes( )
{
int line;
if ( isMesInputLine( PSP ) == YES ) {
if (strncmp(LSP,"<",2)==0) {
if ( get_forum_name_last_str( LSP ) == TRUE ) {
strncpy( ForumNameLine, LSP, LSL);
ForumNameLine[ LSL-2 ] = '\0';
StartMesSw = TRUE;
};
return( FALSE );
};
};
/* PATIO の発言と区別を付けるため */
/* 以下の処理は StartMesSw が TRUE でないと処理しない */
if ( StartMesSw != TRUE ) return( FALSE );
/* 123456789 123456789 123456789 123456 */
if ( matchstr( "番号 発言 (未読) 最新 会議室名", PSP ) == TRUE ) {
SaveTmpKaigishitsuNameLine( MES );
return( FALSE );
};
if ( isMesHyoudaiLine( PSP ) != YES
|| isMesSecondLine( NSP ) != YES
) {
return( FALSE );
};
sayNum=atoi( PSP );
MesNum = atoi( NSP + 1 ); comNum = 0;
if ( NSL > 23 ) {
comNum = atoi( NSP + 23 );
};
set_hatsugen_date( MES, NSP, str );
sayDate = date_to_long( MES, str );
/* 題名のセット */
set_hyoudaiName( MES );
#if VERIFY == YES
if ( verify == TRUE ) {
printf( "isFORUMMes() で "
"会議室番号:%2d 発言番号:%5d コメント元番号:%5d\n"
"の発言を見つけました ↓ \n"
, MesNum, sayNum, comNum
);
present_str_print();
next_str_print();
};
#endif
return( TRUE );
}
void er_memory( const char *com )
{
printf( "%s でメモリーが足りません。", com );
exit( 1 );
}
void er_open( const char *file, int mode, char *mes )
{
char str1[ MAX_FILENAME_LEN + 30 ];
sprintf( str1, "%s で can't open→<%s> ", mes, file);
switch( mode ) {
case 0: strcat( str1, "(read)" ); break;
case 1: strcat( str1, "(write)" ); break;
};
puts( str1 ); exit( 1 );
}
void without_crlf( char *str )
{
while ( *str ) {
if ( *str == '\n' ) { *str = '\0'; break; };
str++;
};
}
const char *last_comma( const char *str )
{
const char *result;
result = str;
while ( *str ) { if ( *str == '.' ) result = str;
str++;
}; return( result );
}
const char *last_yen( const char *str )
{
const char *result;
result = str;
while ( *str ) { if ( *str == '\\' ) result = str;
str++;
}; return( result );
}
void append_yen( char *str )
{
char c;
if ( *str == '\0' ) return;
while ( *str ) str++;
c = *( str -1 );
if ( c != '\\' && c != ':' ) {
*str++ = '\\';
*str = '\0';
};
}
char *next_word( char *ptr )
{
while ( ! isspace( *ptr ) ) ptr++;
while ( isspace( *ptr ) && ( ! iskanji(*ptr) ) ) ptr++;
return( ptr );
}
void set_tmp_file_name( int num , char *FileName )
{
if ( num == COMTREE_TMP_FILE ) {
sprintf( FileName, "%scomtree.tmp", OutDir );
} else if ( num == COMTXT_TMP_FILE ) {
sprintf( FileName, "%scomtxt.tmp", OutDir );
} else if ( num == KAIGISHITSU_TMP_FILE ) {
sprintf( FileName, "%s会議室.tmp", OutDir );
} else if ( num == DL_TMP_FILE ) {
sprintf( FileName, "%sDL.tmp", OutDir );
} else if ( num == COMTREE0_TMP_FILE ) {
sprintf( FileName, "%scomtree0.tmp", OutDir );
#ifdef MAKE_FAPXTREE_TMP
} else if ( num == FAPXTREE_TMP_FILE ) {
sprintf( FileName, "%sfapxtree.tmp", OutDir );
#endif
} else {
sprintf( FileName, "%s$ct%d.tmp", TmpDir, num );
};
}
static int deleteTmpFileNum[] = {
#ifdef MAKE_FAPXTREE_TMP
FAPXTREE_TMP_FILE,
#endif
KAIGISHITSU_TMP_FILE,
DL_TMP_FILE,
COMTXT_TMP_FILE,
/*
COMTREE_TMP_FILE,
COMTREE0_TMP_FILE,
*/
-1
};
void deleteComTreeTmpFile()
{
int i, num;
i = 0;
while( ( num = deleteTmpFileNum[i] ) >= 0 ) {
set_tmp_file_name( num, FileName );
remove( FileName );
i++;
};
}
void OpenComTreeTmpFile( char *Com )
{
set_tmp_file_name( COMTREE0_TMP_FILE, FileName );
if ( ( CT_fpo0= fopen(FileName,"w"))== NULL ) er_open(FileName, 1, Com);
set_tmp_file_name( COMTREE_TMP_FILE, FileName );
/* 下の "a" を "w" に変更したが……… 1993.9.6 */
if ( (CT_fpo=fopen( FileName, "w") ) == NULL ) er_open(FileName, 1, Com);
/* COMTXT_TMP_FILE に 発言の本体を書き出す */
if ( NoTextSw == FALSE ) { /* -t option */
*FileNameSub = '\0'; CT_fpiText = NULL;
set_tmp_file_name( COMTXT_TMP_FILE, FileName );
if((CT_fpoText=fopen(FileName,"ab"))==NULL) er_open(FileName, 1, Com);
};
}
static void (*ct_findfirst_sub)( const char *file , const char *ff_name );
static void ct_findfirst_loop( const char *path )
{
int done;
struct ffblk ffblk;
char f_name[ 256 ];
strcpy( f_name , path ); strcat( f_name , "*.*" ); /* 全ファイルを検索 */
done = findfirst( f_name , &ffblk , FA_DIREC ); /* Directory を指定 */
while ( ! done ) {
strcpy( f_name , path ); strcat( f_name , ffblk.ff_name );
if ( ffblk.ff_attrib == FA_DIREC ) {
if ( strcmp( ffblk.ff_name , "." ) != 0
&& strcmp( ffblk.ff_name , ".." ) != 0
) { /* Sub dir 再帰呼出し */
/* 再帰的に検索しない? */
if ( NoSubDirSw == FALSE ) {
strcat( f_name , "\\" ); ct_findfirst_loop( f_name );
};
};
} else {
/* ファイル名 */
strcpy( ct_findfirst_path, path );
(*ct_findfirst_sub)( f_name , ffblk.ff_name );
};
done = findnext( &ffblk );
};
}
void ct_findfirst(
const char *path,
void (*sub)( const char *file , const char *ff_name )
) {
ct_findfirst_sub = sub;
ct_findfirst_loop( path );
}
char *touppers( char *str0 ) /* 文字列を大文字に変換する */
{
char c , *str1 ;
str1 = str0;
while( ( c = *str1 ) != '\0' ) {
if ( iskanji( c ) ) { str1 += 2; /* 漢字コード */
} else { *str1 = toupper( c );
str1++;
};
};
return( str0 );
}
/* 標題の部分を取り出す */
/*
> 1 2 3 4 5 6
> 123456789 123456789 123456789 123456789 123456789 123456789 123456789
>751 [93/07/24 04:39] GHH01217 RE:CT 0.03L 送ります<山先
>336/338 PGA01332 -なる-(早川) 「実践 MopTerm マクロ講座」その(1)
>00978/00984 GEE00026 MID 白いワニ・・・
>04090/04309 MHG03611 那遊多 訂正(^_^;
> 1 #山先 GHH01217 08/04 07:34
> 題名:お願い
*/
void set_hyoudaiName( int typ )
{
char *p;
char *h_p, *i_p;
int h_c, i_c;
switch( typ ) {
case NEW:
/*************************************************************
> 123456789 123456789 123456789
> 1 93/07/29 全国高校総体開幕、「高校総体情報」スタート
**************************************************************/
h_p = PSP + 6; h_c = PSL - 6;
i_p = PSP + 6; i_c = 0;
case CLIP:
/*************************************************************
>0123456789 123456789 123456789 123456789 123456789 123456789
> 1 1/08 15:09 時: ◎CDROMで特許出願公開
> 2 1/08 12:01 時: ◎松下、米ベンチャー企業に出資
**************************************************************/
h_p = PSP + 18; h_c = PSL - 18;
i_p = PSP + 18; i_c = 0;
break;
case MAIL:
/*
> 1 2 3 4 5 6
> 123456789 123456789 123456789 123456789 123456789 123456789
> 1 #山先 GHH01217 08/04 07:34
> 題名:お願い
*/
h_p = NSP + 10; h_c = NSL - 10;
i_p = PSP + 3; i_c = 17; /* 本名 or ハンドル */
break;
case HP:
/*
> 1 2 3 4 5 6
> 123456789 123456789 123456789 123456789 123456789 123456789
>751 [93/07/24 04:39] GHH01217 RE:CT 0.03L 送ります<山先
*/
h_p = PSP + 37; h_c = PSL - 37;
i_p = PSP + 23; i_c = 8; /* ID */
break;
case MES :
/*
> 1 2 3 4 5 6
> 123456789 123456789 123456789 123456789 123456789 123456789
>336/338 PGA01332 -なる-(早川) 「実践 MopTerm マクロ講座」その(1
>00978/00984 GEE00026 MID 白いワニ・・・
*/
if ( PSP[3] == '/' ) {
h_p = PSP + 38; h_c = PSL - 38;
i_p = PSP + 20; i_c = 16; /* ハンドル */
} else {
h_p = PSP + 39; h_c = PSL - 39;
i_p = PSP + 22; i_c = 16; /* ハンドル */
};
break;
case PATIO:
/*
> 1 2 3 4 5 6
> 123456789 123456789 123456789 123456789 123456789 123456789
>04090/04309 MHG03611 那遊多 訂正(^_^;
*/
h_p = PSP + 39; h_c = PSL - 39;
i_p = PSP + 21; i_c = 16; /* ハンドル */
break;
case BILL:
h_p = PSP + 0; h_c = PSL - 0;
i_p = PSP + 0; i_c = 0; /* 無し */
break;
case LIB:
/***************************************************************
> 1 2 3 4 5
>0123456789 123456789 123456789 123456789 123456789 123456789 1
> 343 GHH01217 92/06/08 57903 19 B CATLOG06.EXE NIFTY通信
***************************************************************/
h_p = PSP + 39; h_c = PSL - 39;
i_p = PSP + 6; i_c = 8; /* ID */
break;
};
h_c -= 2; /* cr lf を除く */
p = HyoudaiLine;
while ( i_c > 0 ) { *p++ = *i_p++; i_c--; };
*p++ = ' ';
while ( h_c > 0 ) { *p++ = *h_p++; h_c--; };
*p = '\0';
}
void set_hatsugen_date( int typ, const char *ptr, char *trg )
{
int i, cnt;
switch( typ ) {
case NEW:
/*************************************************************
> 123456789
> 1 93/07/29 全国高校総体開幕、「高校総体情報」スタート
**************************************************************/
ptr += 6; cnt = 3; break;
case CLIP:
/*************************************************************
> 123456789 123456789 123456789 123456789 123456789 123456789
> 1 1/08 15:09 時: ◎CDROMで特許出願公開
> 2 1/08 12:01 時: ◎松下、米ベンチャー企業に出資
**************************************************************/
ptr += 6; cnt = 4; break;
case MAIL:
/* 1 2 3 4 */
/* 123456789 123456789 123456789 123456789 12 */
/* 1 山本 年秀 GHH01217 05/05 13:12 */
/* 1 #山先 GHH01217 93/10/01 19:11 */
if ( *(ptr+32) == ' ' ) { ptr += 40; cnt = 5;
} else { ptr += 32; cnt = 4;
};
break;
case HP:
/* 1 2 3 4 */
/* 123456789 123456789 123456789 123456789 123456789 1234567 */
/* 001 [92/05/04 16:00] GHH01217 オープンしました */
ptr += 6; cnt = 5; break;
case MES :
/* 1 2 3 4 */
/* 0123456789 123456789 123456789 123456789 1234567 */
/* ( 1) 92/09/18 14:05 コメント数:1 */
/* ( 1) 92/09/18 14:16 00001へのコメント コメント数:1 */
ptr += 7; cnt = 5; break;
case PATIO:
/* 1 2 3 4 */
/* 0123456789 123456789 123456789 123456789 1234567 */
/* ( 1) 93/07/04 14:12 08659へのコメント */
ptr += 7; cnt = 5; break;
case BILL:
cnt = 2; break;
case LIB:
/***************************************************************
> 1 2 3 4 5
> 123456789 123456789 123456789 123456789 123456789 123456789 1
> 343 GHH01217 92/06/08 57903 19 B CATLOG06.EXE NIFTY通信
***************************************************************/
ptr += 15; cnt = 3; break;
};
for( i=0; i<cnt; i++ ) {
*trg++ = *ptr++; *trg++ = *ptr++; ptr++;
};
*trg = '\0';
}
/********************************/
/* 日付情報を内部形式に変換する */
/********************************/
static long date_to_int_data[] = {
535680L, /* 12L * 31L * 24L * 60L 年 */
44640L, /* 31L * 24L * 60L 月 */
1440L, /* 24L * 60L 日 */
60L, /* 時 */
1L /* 分 */
};
static int date_to_int_data_sub[] = {
1 , /* 年 */
1 , /* 月 */
1 , /* 日 */
0 , /* 時 */
0 /* 分 */
};
long date_to_long( int typ, char *date )
{
long d;
int i, s, e;
d = 0;
if ( typ == MAIL || typ == CLIP ) {
/* 以下の判定は手抜きだ 1993.10.2 */
if ( *date == '9' ) { s = 0; e = 6;
} else { s = 1; e = 5;
};
} else if ( typ == BILL ) { s = 0; e = 2;
} else if ( typ == LIB || typ == NEW ) { s = 0; e = 3;
} else { s = 0; e = 5;
};
for ( i = s ; i < e ; i++ ) {
d += (long)(
( *date & 0x0f ) * 10 + ( *(date + 1 ) & 0x0f )
- date_to_int_data_sub[ i ]
) * date_to_int_data[ i ];
date += 2;
if ( ! isdigit( *date ) ) break;
};
return( d );
}
void long_to_date( int typ, char *date , long d )
{
long s;
int i;
char str1[ 24 ];
if ( d < date_to_int_data[0]
/* 1993.10.2 コメントアウト
|| typ == MAIL
*/
) { s = 1;
} else { s = 0;
};
*date = '\0';
for ( i = s ; i < 5 ; i++ ) {
s = d / date_to_int_data[ i ] + (long)date_to_int_data_sub[ i ];
d = d % date_to_int_data[ i ];
sprintf( str1 , "%02ld" , s ); strcat( date , str1 );
};
}
/* DIVIDE_END */
/* DIVIDE_START=ct.h */
/*
コメントツリー作成プログラム ct.h
作 : 山先(NIFTY-ID:GHH01217)
*/
#include <mylib.h>
#include <stdlib.h>
#include <ctype.h>
#include <jctype.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include <dir.h>
#include "extern.h"
/********************************/
/* コメント関係の深さの最大値 */
/* * 2 は文字列として処理する為 */
/********************************/
#define LEVEL_COMMENT ( 35 * 2 )
#define IDX_FILE_NAME "CATLOG.IDX" /* インデックス・ファイル */
#define LINE (1024*2)
#define MAX_FILENAME_LEN 64
#define MAX_BUFSIZE (1024L*20L)
typedef unsigned SayLong;
#define DELETE_SAY (SayLong)0
/* CATLOG の会議室番号の定義 */
#define MES 21 /* フォーラムの会議室である */
#define FORUM_MES 22 /* フォーラムの会議室の一覧である */
#define HP 23 /* Home Party である */
#define MAIL 24 /* 電子メールである */
#define BILL 25 /* 利用料金情報である */
#define COLLECT_ID 26 /* ID収集ファイルである */
#define LIB 27 /* LIB の一覧である */
#define COLLECT_LIB 28 /* IDによる LIB の収集ファイルである */
#define ALL_MAIL 29 /* 1つにまとめた MAIL ファイルである */
#define PATIO 30 /* PATIO である */
#define CLIP 31 /* クリッピングサービスである */
#define NEW 32 /* 今週のお知らせである */
#define COMTREE_TMP_FILE 999
#define COMTREE0_TMP_FILE 998
#define COMTXT_TMP_FILE 997
#define KAIGISHITSU_TMP_FILE 996
#define DL_TMP_FILE 995
#define FAPXTREE_TMP_FILE 994
struct IDX {
SayLong SayNum; /* 発言番号 */
SayLong ComNum; /* コメント番号 */
char ahure;
long SayDate; /* 発言日時 */
long seek; /* tmp0 の seek 位置 */
};
#define MAX_ATTR 31
#define MAX_ATTR1 10
struct IDX2 {
int ForumName; /* ○ フォーラム名 */
int MesNum; /* 会議室番号 */
int ForumNameLine; /* ○ フォーラム名の行 */
int KNL; /* ○ 会議室名の行 */
int FileName; /* ○ ファイル名 */
unsigned SayNum; /* 発言番号 */
unsigned ComNum; /* コメント元番号 */
long SayDate; /* 発言日時 */
long seek; /* seek 位置 byte */
long blen; /* 発言のサイズ byte */
int gyou; /* seek 位置 行 */
int glen; /* 発言のサイズ 行 */
char HyoudaiLine[ 61 ]; /* 題名 */
char ahure;
};
struct IDXS {
char name[ 80 ];
};
#ifdef MAIN
#if VERIFY == YES
int verify = FALSE;
int level_comment = LEVEL_COMMENT;
#endif
struct IDX2 *idx2 = NULL;
struct IDXS *idxs = NULL;
int max_idx2 = 0;
int max_idxs = 0;
int idx2P = 0;
int idxsP = 0;
int OverIdxSw = FALSE;
int CommentLevel = 0;
int Display = TRUE;
int NoTextSw = FALSE;
int NoSubDirSw = FALSE;
int MaxFileSizeSw = FALSE;
long SearchFileSize = 0L;
long MaxSearchFileSize = 1024L*700L;
char FileName[ MAX_FILENAME_LEN ];
char FileNameSub[ MAX_FILENAME_LEN ];
int LineNumber;
int gyou;
char str[ LINE ];
char ForumName[ 20 ];
char OutDir[ MAX_FILENAME_LEN ], InputDir[ MAX_FILENAME_LEN ];
char TmpDir[ MAX_FILENAME_LEN ];
int MesNum ;
SayLong sayNum, comNum;
long sayDate;
char ForumNameLine[ 80 ];
char HyoudaiLine[ 84 ];
char KNL[ 21 ][ 82 ];
struct IDX *idx = NULL;
int max_idx;
int treeMode = 0;
int isCATLOGFileSw = FALSE;
int StartMesSw = FALSE;
int LibNum = 0;
int doFrom1LOGFile;
int doOnlyCurrentCATLOGFile = FALSE;
int HatsugenSu;
FILE *CT_fpi, *CT_fpo, *CT_fpo0;
FILE *CT_fpoText = NULL;
FILE *CT_fpiText = NULL;
char ct_findfirst_path[ MAX_FILENAME_LEN ];
char *attr[ MAX_ATTR ] = {
"OBJ", "EXE", "EXP", "LZH", "BAT", "LIB", "SND", "COM",
"PMB", "PLP", "PLT", "REX", "GGG", "BAS", "FMB", "MML",
"ASM", "C", "H", "LNK", "GUR", "GUS", "DLL", "ITM",
"MAP", "NPB", "BDF", "ISH", "O", "A", "TMP"
};
char *attr1[ MAX_ATTR1 ] = {
"$A0", "$B0", "$C0", "$H0", "$I0", "$L0", "$L1", "$M0",
"$P0", "$N0"
};
#else
#if VERIFY == YES
extern int verify ;
extern int level_comment ;
#endif
extern char *Version; /* 本体は main.c にある */
extern struct IDX2 *idx2;
extern struct IDXS *idxs;
extern int max_idx2 ;
extern int max_idxs ;
extern int idx2P ;
extern int idxsP ;
extern int OverIdxSw ;
extern int CommentLevel ;
extern int Display ;
extern int NoTextSw ;
extern int NoSubDirSw ;
extern int MaxFileSizeSw ;
extern long SearchFileSize ;
extern long MaxSearchFileSize ;
extern char FileName[ MAX_FILENAME_LEN ];
extern char FileNameSub[ MAX_FILENAME_LEN ];
extern int LineNumber;
extern int gyou;
extern char str[ LINE ];
extern char ForumName[ 20 ];
extern char OutDir[ MAX_FILENAME_LEN ], InputDir[ MAX_FILENAME_LEN ];
extern char TmpDir[ MAX_FILENAME_LEN ];
extern int MesNum;
extern SayLong sayNum, comNum;
extern long sayDate;
extern char ForumNameLine[ 80 ];
extern char HyoudaiLine[ 84 ];
extern char KNL[ 21 ][ 82 ];
extern struct IDX *idx;
extern int max_idx;
extern int treeMode ;
extern int isCATLOGFileSw ;
extern int StartMesSw ;
extern int LibNum ;
extern int doFrom1LOGFile;
extern int doOnlyCurrentCATLOGFile ;
extern int HatsugenSu;
extern FILE *CT_fpi, *CT_fpo, *CT_fpo0;
extern FILE *CT_fpoText ;
extern FILE *CT_fpiText ;
extern char ct_findfirst_path[ MAX_FILENAME_LEN ];
extern char *attr[ MAX_ATTR ];
extern char *attr1[ MAX_ATTR1 ];
#endif
extern char *catlog_pool ;
extern char *CPDS;
extern char *LSP , *PSP , *NSP;
extern int LSL , PSL , NSL;
extern long pool_seek_ichi; /* ファイルの中での位置 */
/* DIVIDE_END */
/* DIVIDE_START=extern.h */
/*
GUI-CATLOG補助プログラム extern.h
1993.6.19
このファイルでは、関数の定義をしている。
*/
/*********/
/* lib.c */
/*********/
int isLIBLine();
int isLIBMes();
/***********/
/* check.c */
/***********/
void SortIdx2();
void OverIdx();
void Check1File( const char *f_name , const char *ff_name );
/**********/
/* sort.c */
/**********/
void sortNEW( const int st0 );
void SortMainONFile( );
void SortMainONMemory();
/*********/
/* sub.c */
/*********/
void set_ForumNameLine( int mes );
int matchstr( const char *form, const char *trg );
int isIDname( char *str );
int isHPMes( );
int isMAILMes( );
int isPATIOMes( );
void SaveTmpKaigishitsuNameLine( int typ );
int isFORUMMes( );
void present_str_copy( char *str );
void deleteComTreeTmpFile();
void er_memory( const char *com );
void er_open( const char *file, int mode, char *mes );
void without_crlf( char *str );
const char *last_comma( const char *str );
const char *last_yen( const char *str );
void append_yen( char *str );
char *next_word( char *ptr );
void set_tmp_file_name( int num , char *FileName );
void ct_findfirst( \
const char *path, \
void (*sub)( const char *file , const char *ff_name ) \
);
char *touppers( char *str0 ); /* 文字列を大文字に変換する */
void set_hyoudaiName( int typ );
void set_hatsugen_date( int typ, const char *ptr, char *trg );
long date_to_long( int typ, char *date );
void long_to_date( int typ, char *date , long d );
/**********/
/* file.c */
/**********/
char *catlog_fgets();
int initial_check_pool( const char *FileName );
void end_check_pool();
long catlog_fwrite( FILE *fpo );
void catlog_fprintf( const char *targ , FILE *fpo );
void CT_fcopy( FILE *fpi, long size, FILE *fpo);
long GetFileSize( const char *FileName );
#if VERIFY == YES
void present_str_print();
void next_str_print();
#endif
void pool_malloc( );
/**********/
/* main.c */
/**********/
int mallocIdx();
/**************/
/* マクロ定義 */
/**************/
#define GET_LINE if ( catlog_fgets( ) == NULL ) return
#define GET_LINE2 if ( catlog_fgets( ) == NULL )
/* DIVIDE_END */
# DIVIDE_START=makefile
VER1 = 0
VER2 = 05
VER3 = t # 元のバージョン
VER4 = 0
VER5 = 05
VER6 = u # 現在のバージョン
MemoryModel = c
tc = tcc
lib = tlib
link = tlink
cflags = -m$(MemoryModel) -A -d -N -O -DVERSION="$(VER4).$(VER5)$(VER6)" -DVERIFY=NO
.c.obj :
$(tc) -c $(cflags) -Ie:\tc\include $*
.c.com :
$(tc) $(cflags) -Ie:\tc\include $*
$(link) /c \tc\lib\c0t.obj $*.obj , $* , nul , @listlibs
com_prg = ct.exe
hdr1 = ct.h \tc\include\mylib.h
obj1 = file.obj sub.obj check.obj sort.obj lib.obj load.obj
objV = main.obj
$(com_prg) : $(objV) $(obj1) makefile $(hdr1) all listobj
tlink @listobj
copy $(com_prg) d:\exe
# makebdf $* ct$(VER1)$(VER2) $(VER3) ct$(VER4)$(VER5) $(VER6)
# makebdf -I $* ct$(VER1)$(VER2) $(VER3) ct$(VER4)$(VER5) $(VER6)
makebdf -BI $* ct$(VER1)$(VER2) $(VER3) ct$(VER4)$(VER5) $(VER6)
$(obj1) : $(hdr1)
$(objV) : $(hdr1) makefile # Version 管理
# DIVIDE_END
# -DIVIDE_START=listobj
/c e:\tc\lib\c0c.obj main.obj file.obj sub.obj check.obj sort.obj lib.obj load.obj , ct.exe , nul , e:\tc\lib\emu e:\tc\lib\mathc e:\tc\lib\cc
# DIVIDE_END
REM -DIVIDE_START=m.bat
echo off
:loop
if "%1"=="" goto main
vz %1
:loop2
make
if errorlevel 1 goto error
goto end
:main
vz all
div all
goto loop2
:error
pause
goto loop
:end
REM DIVIDE_END
REM -DIVIDE_START=u.bat
div -u:update.doc all
if errorlevel 1 goto end
div -a:*.c all
div -a:*.h all
div -a:makefile all
div -a:listlibs all
div -a:*.bat all
div -a:readme.doc all
div -a:*.ggg all
:end
REM DIVIDE_END
/* -DIVIDE_START=ct.doc */
------------
CTの使い方
------------
1.CTがすること。
本プログラムは、NIFTYのログを参照して、そのコメントツリーを
表示する物です。
1つの会議室で5040個までの発言についてツリーを作ることが出来
ます。それ以上の発言は扱えませんので、生ログファイルを削除したり
(危険!)、検索するディレクトリを少なくするようにして下さい。
本来は、フォーラムの会議室の発言とPATIOの発言だけを処理すれ
ば良いのですが、追加機能として以下の処理も行えるようにしました。
・HPの発言
・メール
・データライブラリー(以下DLと略す)のリスト
・今週のお知らせ
・クリッピングサービス
・NIFTYの課金情報
ただし、これらの発言等は、発言日時、発言番号の順に並んだ物として表
示されます。
また、DLは、発言番号の位置にDL番号を表示し、DL番号の順に表示
し、リストの参照数の和が異なれば異なる物として表示します。(参照数の
和の多い方が後に表示されます。)
また、課金情報は、発言番号の位置に、1番目の月を表示し、3ヵ月のア
クセス回数の和が異なれば異なる物として表示します。(アクセス回数の和
の多い方が後に表示されます。)
処理の途中で「ESC」キーを押すと、処理を中断します。中断した時、内
部で使用しているTMPファイル(後述)は削除しません。
(1) 扱うファイル
CTが理解できるファイルは、次のファイルです。
┌───────────────────────────┐
│・FAPXを使ってオートでダウンした「生ログファイル」│
│・CATLOGを使って「整理したファイル」 │
└───────────────────────────┘
これ以外のファイルは、フォーラム名や、HP・PATIOの設置者IDが
「UNKNOWN」として処理されたり、PATIOがフォーラムとして処理される
おそれがあります。
また、全く発言を見つけることができないかも知れません。
(2) 無視するファイル
CTが無視するファイルは、明らかにログファイルではないと思われる拡
張子のファイルです。
コマンドライン上で、
ct -z
と実行していただくと、無視するファイルの拡張子が表示されます。
現在、次の拡張子が登録されています。( 41 個)
OBJ EXE EXP LZH BAT LIB SND COM
PMB PLP PLT REX GGG BAS FMB MML
ASM C H LNK GUR GUS DLL ITM
MAP NPB BDF ISH O A TMP $A0
$B0 $C0 $H0 $I0 $L0 $L1 $M0 $P0
$N0
次の拡張子のファイルも無視されます。( 20 個)
$F0 ~ $F9 , $FA ~ $FK
(3) 作成するファイル
CTを実行すると「出力ディレクトリ(OutDir)」(後述)に次のファイルを
作成します。ファイルの内容については後述します。
・comtree.tmp コメントツリーの諸データが書き込まれます。
・comtree0.tmp コメントツリーの標題が書き込まれます。
・comtxt.tmp 発言の本体が書き込まれます。
・会議室.tmp フォーラムの会議室の一覧が書き込まれます。
・DL.tmp DLの一覧が書き込まれます。
また、実行時、次のファイルをMS-DOSの環境変数「tmp」に設定され
たディレクトリ(環境変数「tmp」が設定されていない場合はカレント・ディ
レクトリ)に作成します。
(実行後、削除されます。)
・$ct1.tmp ~ $ct20.tmp
・xxxxxxxx.$H0 HP処理用の内部データです。
・xxxxxxxx.$P0 PATIO処理用の内部データです。
・xxxxxxxx.$F0 ┐
↓ │
xxxxxxxx.$F9 │フォーラムの会議室処理用の内部データです。
xxxxxxxx.$FA │
↓ │
xxxxxxxx.$FK ┘
・xxxxxxxx.$M0 メール発信者の内部データです。
・xxxxxxxx.$L0 DLの内部データです。
・CLIP.$C0 クリッピングサービスの内部データです。
・BILL.$B0 課金情報の内部データです。
・NEW.$N0 「今週のお知らせ」の内部データです。
「xxxxxxxx」の部分には、フォーラム名、HP・PATIOの設定者のI
D番号、メール発信者のID番号が入ります。
なお、CTが起動された場合、上のTMPファイルがあれば全部削除します
ので、同じ名前のファイルが無いことを充分ご確認の上、CTを実行して下さ
い(削除して良いかどうかの確認はしません)。同名のファイルはないと思い
ますが………。
出力するファイルはいずれもテキストファイルです。(エディタ等で見るこ
とができます)
(4) MS-DOSの環境変数の参照
CTは、次の2つの環境変数を参照しています。
ctusr
tmp
「ctusr」は、CTに対してオプションスイッチを設定する働きがあります。
スイッチの意味はコマンドラインで指定するスイッチと全く同じです。
ただし、スイッチの優先順序があります。
優先順位が一番高いのはコマンドラインからの指定です。ここで、指定す
ると環境変数で指定していても無視されます。
優先順位が次に高いのは、環境変数「ctusr」での指定です。これは、CT
のデフォルトの値を無視します。
優先順位が最も低いのは、CTのデフォルトの値です。
「tmp」は、CTが内部で作成するTMPファイルを書き出すドライブ:デ
ィレクトリを指定します。この設定がない場合はCTを起動した時のカレント
ディレクトリにTMPファイルが書き出されます。
「tmp」をRAMディスクに設定しておくと処理が高速になります。
2.CTの実行の仕方
コマンドライン上で、次のように実行して下さい。
ct [-option] [-o OutDir名] InputDir名 [InputDir名] [InputDir名]...
または、
ct [-option] [-o OutDir名] File名 [File名] [File名]...
または、
ct [-option] @Def-File名
オプションには必ず「-」を使って下さい。
「-」の後ろには複数のオプションを指定することができます。
例: -TDo
また、別々に指定することもできます。
例: -T -D -o
また、矛盾する指定を同時に指定した場合は、後で(右側で)指定した方が
有効になります。
例: -Todt
この場合「t」が有効になります。
「-」の無いものは入力するファイル名かディレクトリ名として判断します。
ということは、逆に、「-」から始まるファイルやディレクトリは入力として
扱えないということです。適当な名前に変更(rename)してCTを起動して下
さい。
「-o OutDir名」の指定が無い場合は、「comtree.tmp」「comtree0.tmp」
「会議室.tmp」「DL.tmp」ファイルはカレント・ディレクトリに書き出されま
す。
オプションは、次のものが指定できます。
第1群 (ファイルの検索指定)
-A ・・・・・・・ CATLOGのカレント・ファイル(拡張子0)のみ検索する
-a ・・・・・・・ * CATLOGの全ての整理ファイルを検索する
CATLOGは、会議室が新しくオープンされた場合とか、ファ
イルの大きさが大きくなった場合等に、それまで書き出していたフ
ァイルの名前を変更して、新しいファイルを作り、そのファイルに
見つけた発言を追加していきます。そのファイル名はいつも同じで、
フォーラムの会議室の場合「MESxx_00.TXT」となり、HomePa
rtyの場合は「HP開設者ID.HP0」、PATIOの場合「PA
TIO開設者ID.PA0」、メールの場合「メール発信者ID.ML0」
となります。(CATLOGでは、このファイルをカレント・ファ
イルと名付けています)
そして、整理して出来上がったファイルに対してコメントツリー
を作る場合、通常は(デフォルト)古いファイルに対してもコメン
トツリーを作ろうとしますが、このスイッチを指定することにより、
検索の対象をカレント・ファイルだけに絞ることができます。(処
理時間が短くなるということです)。
-F数 ・・・・・ 数Kバイトまでファイルを検索する
-f ・・・・・・・ * サイズで中断しない
これは、発言が入っているかも知れないファイルを読み込むのに、
「数」で指定した以上のサイズ(合計値)のファイルは読み込まな
い、というスイッチです。
例: -F1024
この場合、読み込むファイルが 1024 × 1024 バイトを超える
と、以後の指定のファイルは無視されます。
-R ・・・・・・・ サブディレクトリのファイルを検索しない
-r ・・・・・・・ * サブディレクトリのファイルを検索する
第2群 (出力ディレクトリの指定)
-o ・・・・・・・ 「comtree.tmp」「comtree0.tmp」「会議室.tmp」の出力先の
指定
入力するファイルやディレクトリの、指定よりも先に指定して下さい。
そうしないと「会議室.tmp」というファイルがカレント・ディレクト
リに作られてしまいます。
第3群 (高速化のための処理の指定)
-D ・・・・・・・ 標題等を画面上に表示しない
-d ・・・・・・・ * 標題等を画面上に表示する
-T ・・・・・・・ 発言の本体(comtxt.tmp)を出力しない
-t ・・・・・・・ * 発言の本体(comtxt.tmp)を出力する
第4群 (ツリーの作り方の指定)
-1 ・・・・・・・ ベタのまま、発言の標題を表示する
-2 ・・・・・・・ * コメントツリーで発言の標題を表示する
第5群 (設定ファイルの読み込み指定)
@ ・・・・・・・ コマンド・ラインに記述しきれない場合や同一の処理を
繰り返し行う場合に、コマンド・ラインに記述する書式
で指定します。
第6群 (補助的な指定)
-z ・・・・・・・ 読み飛ばす拡張子を表示する( 40 個 )
実行後、終了します。
★ 「*」 は、デフォルトの設定です
3.「入力ディレクトリ(InputDir)」「出力ディレクトリ(OutDir)」について
(1) 入力ディレクトリ(InputDir)
ログ・ファイルがどのドライブ:ディレクトリにあるのか指定します。
指定の仕方はMS-DOSの方法です。
カレント・ディレクトリのファイルを検索するのであれば「.」を指定します。
この部分にファイル名を指定すると、指定したファイルだけを読み込んで発
言を探索します。
MS-DOSのワイルド・カードが使用できます。
設定を省略することはできません。
ディレクトリ名の最後に「\ 」を付ける必要はありません。
(2) 出力ディレクトリ(OutDir)
CTが作るファイルをどのドライブ:ディレクトリに書き出すかを指定しま
す。
指定の仕方はMS-DOSの方法です。
この指定は省略することができます。省略されると、起動時のカレント・デ
ィレクトリにファイルを書き出します。
ディレクトリ名の最後に「\ 」を付ける必要はありません。
この部分にRAMディスクを指定すると、少し高速になります。
4.CTが作るファイルについて。
(1) comtree.tmp コメントツリーの諸データが書き込まれます。
このデータは、3行が1セットになって、3行で1つの発言についてのデー
タを表します。
そして、「comtree0.tmp」に書き出される標題だけのデータや、「comtxt.t
mp」に書き出される発言の本体と、同じ順番で書き出されています。
その内容は次のようになっています。
1行目はフォーラム名の行(NIFTYの形式)が入ります。
以後フォーラム名が変わる場合は、「フォーラム名変更」という文字列
が入ります。会議室番号は入りません。
以後会議室番号が変わる場合は、「会議室名変更」という文字列が入り
ます。会議室番号は入りません。
2行目は、発言に関するデータが入ります。その意味は下の通りです。
"%5ld %5ld %8ld %8ld %5d %5d %10ld\n"
| | | | | | ↓
| | | | | ↓ 発言日時(10文字の数字)
| | | | ↓ 発言の終了行(5文字の数字)
| | | ↓ 発言の開始行(5文字の数字)
| | ↓ 発言の終了バイト数(8文字の数字)
| ↓ 発言の開始バイト数(8文字の数字)
↓ コメント元番号(5文字の数字)
発言番号(5文字の数字)
「フォーラム名変更」「会議室名変更」の場合は、それぞれ該当の名前
が入ります。
3行目は発言のあったファイル名がパス名付きで書き出されます。
「フォーラム名変更」「会議室名変更」の場合は、改行だけです。
(2) comtree0.tmp コメントツリーの標題が書き込まれます。
内容は、画面上に表示される文字列をそのままファイルに書き込んだ物です。
発言のツリーだけを表示すると、どのフォーラムのどの会議室の発言か分か
りにくいので、それらがわかるデータ(標題)を入れてあります。
(3) comtxt.tmp 発言の本体が書き込まれます。
各発言の行頭には次の行が入っています。これらの文字列を検索することに
より、エディタ等を使って発言を読むことができます。
HPの場合 *****log整理(HP:xxxxxxxx ) ファイル名 *****
PATIOの場合 *****log整理(PATIO:xxxxxxxx ) ファイル名 *****
メールの場合 *****log整理(MAIL:xxxxxxxx ) ファイル名 *****
DLの場合 *****log整理(FORUM:xxxxxxxx LIB:xx) ファイル名 *****
フォーラムの場合 *****log整理(FORUM:xxxxxxxx MES:xx) ファイル名 *****
今週のお知らせの場合 *****log整理(今週のお知らせ ) ファイル名 *****
クリッピングサービス の場合 *****log整理(クリッピングサービス ) ファイル名 *****
課金情報の場合 *****log整理(利用料金情報 ) ファイル名 *****
「xxxxxxxx」の部分は8文字で、左詰めです。
「xx」の部分は2文字で、右詰めです。
(4) 会議室.tmp フォーラムの会議室の一覧が書き込まれます。
フォーラムの会議室の一覧が書き込まれます。
形式は、次のようになっています。
┌──────────────────────────┐
│FORUM:xxxxxx │
│<FMフォーラム????館) > xxxxxx │
│番号 発言 (未読) 最新 会議室名 │
│ 1 1 ( 1) 08/21 FAPXの部屋 │
└──────────────────────────┘
フォーラムとフォーラムの間には1行の空行があります。
また、会議室の一覧に当たる文字列がなかった場合、このファイルは作成さ
れません。
(5) DL.tmp DLの一覧が書き込まれます。
DLの一覧が書き込まれます。
形式は、次のようになっています。
┌──────────────────────────┐
│LIB:xxxxxx │
│<FMフォーラム????館) > xxxxxx │
│番号 総数 登録済 最新 ライブラリ名 │
│ 1 1 ( 1) 08/21 FAPX関連 │
└──────────────────────────┘
フォーラムとフォーラムの間には1行の空行があります。
また、DLの一覧に当たる文字列がなかった場合、このファイルは作成さ
れません。
(6) TMPファイルについて
実行時、次のファイルをMS-DOSの環境変数「tmp」に設定されたディレ
クトリ(環境変数「tmp」が設定されていない場合はカレント・ディレクトリ)
に作成します。(実行後、削除されます。)
・$ct1.tmp ~ $ct20.tmp
・xxxxxxxx.$H0 HP処理用の内部データです。
・xxxxxxxx.$P0 PATIO処理用の内部データです。
・xxxxxxxx.$F0 ┐
↓ │
xxxxxxxx.$F9 │フォーラムの会議室処理用の内部データです。
xxxxxxxx.$FA │
↓ │
xxxxxxxx.$FK ┘
・xxxxxxxx.$M0 メール発信者の内部データです。
・xxxxxxxx.$L0 DLの内部データです。
・CLIP.$C0 クリッピングサービスの内部データです。
・BILL.$B0 課金情報の内部データです。
・NEW.$N0 「今週のお知らせ」の内部データです。
「xxxxxxxx」の部分には、フォーラム名、HP・PATIOの設定者のI
D番号、メール発信者のID番号が入ります。
ファイルの内容は、1つの発言について6行で記述しています。
1行目:フォーラム名と会議室番号が入ります。
フォーラム名は8バイトで会議室番号との間には空白があります。
2行目:フォーラム名の行が入ります。次のような行です。
<FMTOWNS フォーラム 1 (基本編) > FTOWNS1
3行目:会議室番号の行が入ります。会議室の一覧から得ています。
16 470 ( 5) 08/15 MOPTERM と 仲間たち 【Q&A/交換】
4行目:発言があったファイル名が入ります。
5行目:発言に関するデータが入ります。「comtree.tmp」と同じ書式です。
6行目:発言者のハンドル(ID)と発言の題名が入ります。
なお、CTが起動された場合、上のTMPファイルがあれば全部削除します
ので、カレント・ディレクトリやMS-DOSの環境変数「tmp」で指定したデ
ィレクトリに、同じ名前のファイルが無いことを充分ご確認の上、CTを実行
して下さい(削除して良いかどうかの確認はしません)。同名のファイルはな
いと思いますが………。
また、CTを実行している間に「ESC」キーを押すと、処理が中断されます。
この時、上記のTMPファイルはそのままディレクトリに残ってしまいます。
5.実行例
(1) 実行例1
「f:\log」にあるファイルを検索してツリーを作る。
できたファイルは「f:\tmp」に書き出す。
「comtxt.tmp」を作る。
ct -o f:\tmp f:\log
(2) 実行例2
「f:\log」にあるファイルを検索して、ツリーを作る。
できたファイルはカレント・ディレクトリに書き出す。
ただし、「comtxt.tmp」ファイルは作らない。
ct -T f:\log
例1と異なる所はオプション指定を付加していることです。
(3) 実行例3
「f:\log\ffmhob 」にあるファイルを検索して、ツリーを作る。
できたファイルは「f:\tmp」に書き出す。
「comtxt.tmp」ファイルは作らない。
ct -o f:\tmp -DT f:\log\ffmhob
(4) 実行例4 → できるだけ高速に処理を行う。
MS-DOSの環境変数「tmp」にRAMディスクを指定する。
例えば、「G:」ドライブがRAMディスクだったとすると、システム
起動時に最初に実行する「autoexec.bat」というバッチファイルに
set tmp=g:
という1行を追加しておくと設定できます。
「-D」オプションを指定する。
「-T」オプションを指定する。
使い方はだいたい分かっていただいたでしょうか?
6.問題点
(1) とにかく、処理に時間がかかるということです。
CATLOGで整理したファイルに対して処理を行うと、数分~数十分も
待たされます。どうするかが今後の問題です。
(2) かなりたくさんのTMPファイルを作ります。
1つの会議室につき、1ファイルを作ります。10のフォーラムで10の
会議室の発言があると100個のTMPファイルができます。
(3) 「-T」オプションを指定しない場合、「comtxt.tmp」というファイルを書
き出す為、発言と同じ大きさのファイルができてしまうということです。
(それ以外のファイルはそれ程大きくはないんですが)
(4) ファイルに書き出す際、ちゃんと書き出されたかどうかのチェックは行っ
ていません(はっきり言って手抜きです)。できるだけ残り容量の大きいド
ライブに環境変数「tmp」や「出力ディレクトリ(OutDir)」を指定して欲し
いと思います。
(5) 実行時、メモリーのヒープ領域を大量に確保します。充分なメモリーが無
い場合は処理できる発言数が少なくなるばかりか、「発言の数が多くて処理
できません」というエラーメッセージを出して中断することもあります。
7.作成協力者
以下の方々にご協力いただいて、本プログラムは作られました。
ここに紹介して感謝の念を表したいと思います。
PEE01244 Yama-chan さん
PFG02442 <Nakatani> さん
QFH02666 『コノミ』 さん
GFF00430 えんでん さん
VFA03257 フェイス さん
PED00201 JINX さん
HCD01017 猫飛 さん
HAD01045 SAINT さん
PGA01332 -なるチャン-☆ さん
HAC01216 doubt さん
GDH03105 だいへいくん さん
GBH00541 DORAGON さん
HFB02053 RENCHAN さん
JAG00217 てげてげ さん
HGE00530 し~なくん さん
8.著作権
本プログラムはNIFTY-ID:GHH01217 山先(やません)に
著作権があるものとします。しかし、その使用、配付は自由に行っていただい
てかまいません。(FAPXには、同梱してもらうことにしました)
9.何かありましたら。
NIFTYのフォーラムFTOWNS1の「MopTermとその仲間たち」
の会議室に発言されるか、私あてメールを下さい。
GHH01217 山先
/* DIVIDE_END */
/* -DIVIDE_START=ct.ggg */
======================================================================
【ソフト 名】 ct.exe NIFTYコメントツリー作成プログラム Version 0.05u
【登 録 名】 ct005u.lzh (LHAで解凍して下さい)
【検索 キー】 1:CT 2:MOPTERM 3:FAPX 4:CATLOG
【著作権 者】 山先 GHH01217
【開発 環境】 Turbo-C Ver2.0 + Vz → ct.exe
【対応 機種】 MS-DOS 汎用
運用推奨:HDD上
【動作 確認】 FM-TOWNS20F + 8M-RAM コンソール上
【公 開 日】 93/08/26
【ソフトウェア種別】 通信関連。フリー・ソフトウェア。
======================================================================
【ソフト紹介】
本プログラムは、NIFTYのログを参照して、そのコメントツリーを表
示する物です。
CTが理解できるファイルは、次のファイルです。
┌───────────────────────────┐
│・FAPXを使ってオートでダウンした「生ログファイル」│
│・CATLOGを使って「整理したファイル」 │
└───────────────────────────┘
本来は、フォーラムの会議室の発言とPATIOの発言だけを処理すれば
良いのですが、追加機能としてそれ以外のデータも処理するようにしていま
す。ただし、発言番号の順等に並んだ物として表示されます。
解凍すると以下のファイルが出て来ます。
ct.exe ……………… プログラム本体
ct.doc ……………… CTの説明
ct.ggg ……………… このファイル(概要)
詳しくはCT.DOCをお読み下さい。
ダウンロードファイル名を ct005u.lzh として下さい。
GHH01217 山先
/* DIVIDE_END */